// File: /workspace/github_c_makefile_star2_O2/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
subq $0x18, %rsp
cmpl $0x1, 0x10(%rdi)
jne 0x6316
movq %rdi, %rbx
xorps %xmm0, %xmm0
movaps %xmm0, (%rsp)
movq 0x28(%rdi), %r12
testq %r12, %r12
je 0x654a
xorl %r14d, %r14d
pushq $0x10
popq %r15
movl 0x10(%r12), %eax
cmpq %rax, %r14
jae 0x6325
movq %r12, %rdi
movq %r14, %rsi
callq 0x4c82
testq %rax, %rax
je 0x648c
movq %rax, %r13
movq %r12, 0x8(%rax)
movq %r15, %rdi
callq 0x37fa
testq %rax, %rax
je 0x640d
movq %r13, 0x8(%rax)
movq 0x8(%rsp), %rcx
xorl %edx, %edx
testq %rcx, %rcx
setne %dl
leaq 0x8(%rsp), %rsi
cmoveq %rsi, %rcx
movq %rax, (%rcx)
movq %rax, (%rsp,%rdx,8)
incq %r14
movq 0x28(%rbx), %r12
jmp 0x62b6
movq 0x7c8b(%rip), %rax      # 0xdfa8
incq (%rax)
jmp 0x641c
movq %rbx, 0x10(%rsp)
movq (%rsp), %rdi
testq %rdi, %rdi
je 0x642b
movq (%rdi), %rax
movq %rax, (%rsp)
testq %rax, %rax
jne 0x6349
andq $0x0, 0x8(%rsp)
movq 0x8(%rdi), %r15
callq 0x3070
xorl %r12d, %r12d
movl 0x10(%r15), %eax
cmpq %rax, %r12
jae 0x632a
movq %r15, %rdi
movq %r12, %rsi
callq 0x4c82
movq %rax, %r13
movq %r15, %rdi
movq %r12, %rsi
callq 0x5bef
testq %r13, %r13
je 0x64ba
movl %eax, %ebp
pushq $0x10
popq %rdi
callq 0x37fa
testq %rax, %rax
je 0x640d
movq %r13, 0x8(%rax)
movq 0x8(%rsp), %rcx
xorl %edx, %edx
testq %rcx, %rcx
setne %dl
leaq 0x8(%rsp), %rsi
cmoveq %rsi, %rcx
movq %rax, (%rcx)
movq %rax, (%rsp,%rdx,8)
movq 0x8(%r15), %r14
testq %r14, %r14
je 0x64e8
movq 0x28(%rbx), %rbx
cmpq %rbx, %r14
je 0x63e0
movq %r14, %rdi
movl %ebp, %esi
callq 0x4d53
testq %rax, %rax
jne 0x63e0
movq 0x8(%r14), %r14
testq %r14, %r14
jne 0x63c1
jmp 0x6449
movq %r14, %rdi
movl %ebp, %esi
callq 0x4d53
movq %rax, 0x8(%r13)
testq %rax, %rax
jne 0x6400
movq %rbx, 0x8(%r13)
testq %rbx, %rbx
je 0x6519
incq %r12
movq 0x10(%rsp), %rbx
jmp 0x6355
movq %rsp, %rdi
callq 0x381c
callq 0x30e0
xorl %eax, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x2, 0x10(%rbx)
incl 0x30(%rbx)
movq %rsp, %rdi
callq 0x381c
movq 0x7b7c(%rip), %rax      # 0xdfc0
jmp 0x631d
movq 0x7ba8(%rip), %rbx      # 0xdff8
movq (%rbx), %rdi
leaq 0x1bd6(%rip), %rsi      # 0x8030
leaq 0x42c1(%rip), %rdx      # 0xa722
leaq 0x4327(%rip), %rcx      # 0xa78f
leaq 0x463d(%rip), %r9       # 0xaaac
movl $0x274, %r8d            # imm = 0x274
xorl %eax, %eax
callq 0x31b0
movq (%rbx), %rdi
callq 0x3230
pushq $0x1
popq %rdi
callq 0x3310
movq 0x7b65(%rip), %rbx      # 0xdff8
movq (%rbx), %rdi
leaq 0x1b93(%rip), %rsi      # 0x8030
leaq 0x427e(%rip), %rdx      # 0xa722
leaq 0x42e4(%rip), %rcx      # 0xa78f
leaq 0x4218(%rip), %r9       # 0xa6ca
movl $0x248, %r8d            # imm = 0x248
jmp 0x6475
movq 0x7b37(%rip), %rbx      # 0xdff8
movq (%rbx), %rdi
leaq 0x1b65(%rip), %rsi      # 0x8030
leaq 0x4250(%rip), %rdx      # 0xa722
leaq 0x42b6(%rip), %rcx      # 0xa78f
leaq 0x41ea(%rip), %r9       # 0xa6ca
movl $0x263, %r8d            # imm = 0x263
jmp 0x6475
movq 0x7b09(%rip), %rbx      # 0xdff8
movq (%rbx), %rdi
leaq 0x1b37(%rip), %rsi      # 0x8030
leaq 0x4222(%rip), %rdx      # 0xa722
leaq 0x4288(%rip), %rcx      # 0xa78f
leaq 0x459e(%rip), %r9       # 0xaaac
movl $0x26e, %r8d            # imm = 0x26E
jmp 0x6475
movq 0x7ad8(%rip), %rbx      # 0xdff8
movq (%rbx), %rdi
leaq 0x1b06(%rip), %rsi      # 0x8030
leaq 0x41f1(%rip), %rdx      # 0xa722
leaq 0x4257(%rip), %rcx      # 0xa78f
leaq 0x4279(%rip), %r9       # 0xa7b8
movl $0x27b, %r8d            # imm = 0x27B
jmp 0x6475
movq 0x7aa7(%rip), %rbx      # 0xdff8
movq (%rbx), %rdi
leaq 0x1ad5(%rip), %rsi      # 0x8030
leaq 0x41c0(%rip), %rdx      # 0xa722
leaq 0x4226(%rip), %rcx      # 0xa78f
leaq 0x4238(%rip), %r9       # 0xa7a8
movl $0x244, %r8d            # imm = 0x244
jmp 0x6475