// File: /workspace/github_c_makefile_star2_O1/WojciechMula[P]pyahocorasick/src/Automaton.c
// Function: automaton_make_automaton
static PyObject*
automaton_make_automaton(PyObject* self, PyObject* args) {
#define automaton ((Automaton*)self)

    AutomatonQueueItem* item;
    List queue;
    unsigned i;

    TrieNode* node;
    TrieNode* child;
    TrieNode* state;
    TRIE_LETTER_TYPE letter;


    if (automaton->kind != TRIE)
        Py_RETURN_FALSE;

    list_init(&queue);

    // 1. setup nodes at first level: they fail back to the root
    ASSERT(automaton->root);

    for (i=0; i < automaton->root->n; i++) {
        TrieNode* child = trienode_get_ith_unsafe(automaton->root, i);
        ASSERT(child);
        // fail edges go to the root
        // every other letters loop on root - implicit (see automaton_next)
        child->fail = automaton->root;

        item = (AutomatonQueueItem*)list_item_new(sizeof(AutomatonQueueItem));
        if (item) {
            item->node = child;
            list_append(&queue, (ListItem*)item);
        }
        else
            goto no_mem;
    }

    // 2. make links
    while (true) {
        AutomatonQueueItem* item = (AutomatonQueueItem*)list_pop_first(&queue);
        if (item == NULL)
            break;
        else {
            node = item->node;
            memory_free(item);
        }

        for (i=0; i < node->n; i++) {
            child  = trienode_get_ith_unsafe(node, i);
            letter = trieletter_get_ith_unsafe(node, i);
            ASSERT(child);

            item = (AutomatonQueueItem*)list_item_new(sizeof(AutomatonQueueItem));
            if (item) {
                item->node = child;
                list_append(&queue, (ListItem*)item);
            }
            else
                goto no_mem;

            state = node->fail;
            ASSERT(state);
            ASSERT(child);
            while (state != automaton->root and\
                   not trienode_get_next(state, letter)) {

                state = state->fail;
                ASSERT(state);
            }

            child->fail = trienode_get_next(state, letter);
            if (child->fail == NULL)
                child->fail = automaton->root;

            ASSERT(child->fail);
        }
    }

    automaton->kind = AHOCORASICK;
    automaton->version += 1;
    list_delete(&queue);
    Py_RETURN_NONE;
#undef automaton

no_mem:
    list_delete(&queue);
    PyErr_NoMemory();
    return NULL;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
cmpl $0x1, 0x10(%rdi)
jne 0x67b0
movq %rdi, %r14
cmpq $0x0, 0x28(%rdi)
je 0x69ae
movq 0x28(%r14), %r12
cmpl $0x0, 0x10(%r12)
je 0x67cd
xorl %r15d, %r15d
xorl %ebx, %ebx
xorl %edi, %edi
movq %rdi, %rbp
movq %r12, %rdi
movq %r15, %rsi
callq 0x5737
testq %rax, %rax
je 0x69a9
movq %rax, %r13
movq %r12, 0x8(%rax)
movl $0x10, %edi
callq 0x3370
testq %rax, %rax
je 0x6789
movq $0x0, (%rax)
movq %r13, 0x8(%rax)
xorl %ecx, %ecx
testq %rbx, %rbx
je 0x6793
movq %rbp, %rdi
movq %rax, (%rbx)
jmp 0x6796
movl $0x9, %ecx
movq %rbp, %rdi
jmp 0x6799
movq %rax, %rdi
movq %rax, %rbx
testl %ecx, %ecx
jne 0x67bf
incq %r15
movq 0x28(%r14), %r12
movl 0x10(%r12), %eax
cmpq %rax, %r15
jb 0x6742
jmp 0x67d1
movq 0x97f1(%rip), %rax      # 0xffa8
incq (%rax)
jmp 0x6986
cmpl $0x9, %ecx
je 0x6968
jmp 0x6986
xorl %edi, %edi
xorl %ebx, %ebx
movq %r14, (%rsp)
testq %rdi, %rdi
je 0x67e6
movq (%rdi), %r14
testq %r14, %r14
cmoveq %r14, %rbx
jmp 0x67eb
movq %rdi, %r14
xorl %edi, %edi
testq %rdi, %rdi
je 0x6916
movq 0x8(%rdi), %r15
callq 0x3070
xorl %eax, %eax
cmpl $0x0, 0x10(%r15)
je 0x6922
xorl %r12d, %r12d
movq %r15, %rdi
movq %r12, %rsi
callq 0x5737
movq %rax, %r13
movq %r15, %rdi
movq %r12, %rsi
callq 0x6044
testq %r13, %r13
je 0x699a
movl %eax, %ebp
movl $0x10, %edi
callq 0x3370
testq %rax, %rax
je 0x691d
movq $0x0, (%rax)
movq %r13, 0x8(%rax)
movq %rax, %rdi
testq %rbx, %rbx
je 0x685d
movq %rax, (%rbx)
movq %r14, %rdi
movq 0x8(%r15), %rdx
testq %rdx, %rdx
je 0x699f
movq (%rsp), %rcx
movq 0x28(%rcx), %rcx
cmpq %rcx, %rdx
je 0x68b6
movl 0x10(%rdx), %r8d
testq %r8, %r8
je 0x68a8
movq 0x18(%rdx), %rsi
shlq $0x2, %r8
leaq (%r8,%r8,2), %r9
xorl %r8d, %r8d
cmpl %ebp, (%rsi,%r8)
je 0x68a0
addq $0xc, %r8
cmpq %r8, %r9
jne 0x688f
jmp 0x68a8
cmpq $0x0, 0x4(%rsi,%r8)
jne 0x68b6
movq 0x8(%rdx), %rdx
testq %rdx, %rdx
jne 0x6872
jmp 0x6995
movl 0x10(%rdx), %esi
testq %rsi, %rsi
je 0x68dc
movq 0x18(%rdx), %rdx
shlq $0x2, %rsi
leaq (%rsi,%rsi,2), %rsi
xorl %r8d, %r8d
cmpl %ebp, (%rdx,%r8)
je 0x68e0
addq $0xc, %r8
cmpq %r8, %rsi
jne 0x68cd
xorl %edx, %edx
jmp 0x68e5
movq 0x4(%rdx,%r8), %rdx
testq %rdx, %rdx
cmovneq %rdx, %rcx
movq %rcx, 0x8(%r13)
testq %rcx, %rcx
je 0x69a4
incq %r12
movl 0x10(%r15), %ecx
movq %rax, %rbx
movq %rdi, %r14
cmpq %rcx, %r12
jb 0x680d
movq %rax, %rbx
xorl %eax, %eax
jmp 0x6925
movl $0xb, %eax
jmp 0x6922
movl $0x9, %eax
movq %r14, %rdi
testl %eax, %eax
movq (%rsp), %r14
je 0x67d5
cmpl $0x9, %eax
je 0x6968
cmpl $0xb, %eax
jne 0x6986
movl $0x2, 0x10(%r14)
incl 0x30(%r14)
testq %rdi, %rdi
je 0x695c
movq (%rdi), %rbx
callq 0x3070
movq %rbx, %rdi
testq %rbx, %rbx
jne 0x694c
movq 0x965d(%rip), %rax      # 0xffc0
jmp 0x67b7
testq %rdi, %rdi
je 0x697d
movq (%rdi), %rbx
callq 0x3070
movq %rbx, %rdi
testq %rbx, %rbx
jne 0x696d
callq 0x30e0
xorl %eax, %eax
jmp 0x6986
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x4272
callq 0x433e
callq 0x42fa
callq 0x42b6
callq 0x422e
callq 0x4382