// File: /workspace/github_c_makefile_star2_O3/coyove[P]chann/./src/general.cpp
// Function: unq_new_reply(unqlite*, int, char const*, char const*, char const*, char const*, char const*, bool)
int unq_new_reply(unqlite *pDb, 
    int id, 
    const char* content, 
    const char* title, 
    const char* ip, 
    const char* username, 
    const char* image, bool sega)
{
    struct Thread *r = unq_read_thread(pDb, id);
    struct Thread *root = unq_read_thread(pDb, 0);
    struct Thread *self = r;
    struct Thread *t = new Thread();
    bool reply2reply = false;

    if (r->state & THREAD_REPLY) reply2reply = true;

    char contentkey[16];
    unqlite_util_random_string(pDb, contentkey, 15);
    contentkey[15] = 0;
    unq_write_string(pDb, contentkey, content, false);

    strncpy(t->content, contentkey, 16);
    strncpy(t->author, title, 64);
    strncpy(t->email, ip, 64);
    strncpy(t->ssid, username, 10);
    strncpy(t->imgSrc, image, 16);

    unqlite_commit(pDb);
    t->state = THREAD_REPLY + NORMAL_DISPLAY;
    if (sega) t->state += SAGE_THREAD;

    time_t rawtime;
    time(&rawtime);
    t->date = rawtime;

    if (r->childThread == 0){ //no reply yet
        int newkey = ++root->childCount;// nextCounter(pDb);
        t->nextThread = newkey;
        t->prevThread = newkey;
        t->childThread = 0;
        t->parentThread = r->threadID;
        t->threadID = newkey;
        //it's strange and wired but we update the count of children here
        t->childCount = 1;
        unq_write_thread(pDb, newkey, t, false);
        r->childThread = newkey;
        unq_write_thread(pDb, r->threadID, r, false);
    }
    else{ // construct a circled linked list of threads
        r = unq_read_thread(pDb, r->childThread);
        r->childCount++;
        
        struct Thread *rp;
        if (r->prevThread == r->threadID && r->nextThread == r->threadID) // only one child
            rp = r;
        else
            rp = unq_read_thread(pDb, r->prevThread);

        int newkey = ++root->childCount; //nextCounter(pDb);

        t->prevThread = r->prevThread;
        t->nextThread = r->threadID;
        t->childThread = t->parentThread = 0;
        t->threadID = newkey;

        r->prevThread = newkey;
        rp->nextThread = newkey;

        unq_write_thread(pDb, newkey, t, false);
        unq_write_thread(pDb, r->threadID, r, false);
        unq_write_thread(pDb, rp->threadID, rp, false);

    }

    
    if (self->prevThread == 0 || self->state & SAGE_THREAD || t->state & SAGE_THREAD || reply2reply){
        //under certain circumstance the thread won't be pushed to the top
        //1. already at top
        //2. is a sega thread
        //3. has a sega reply
        //4. what it replies to is a comment itself
    }
    else{//push the replied thread to the top
        if (self->prevThread) { 
            struct Thread* sp = unq_read_thread(pDb, self->prevThread);
            sp->nextThread = self->nextThread;
            unq_write_thread(pDb, sp->threadID, sp, false);

            if (self->nextThread){
                struct Thread* sn = unq_read_thread(pDb, self->nextThread);
                sn->prevThread = sp->threadID;
                unq_write_thread(pDb, sn->threadID, sn, false);
            }
        }

        self->nextThread = root->nextThread;
        self->prevThread = 0;
        root->nextThread = self->threadID;

        if (self->nextThread){
            struct Thread* sn = unq_read_thread(pDb, self->nextThread);
            sn->prevThread = self->threadID;
            unq_write_thread(pDb, sn->threadID, sn, false);
        }

        unq_write_thread(pDb, self->threadID, self, false);

    }

    unq_write_thread(pDb, 0, root, false);
    unqlite_commit(pDb);

    
    delete root;
    if (self != r) delete self;
    delete r;
    delete t;

    return 1;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %r9, 0x20(%rsp)
movq %r8, 0x18(%rsp)
movq %rcx, 0x10(%rsp)
movq %rdx, %rbp
movq %rdi, %r14
movb 0x88(%rsp), %r12b
callq 0xe181
movq %rax, %rbx
movq %r14, %rdi
xorl %esi, %esi
callq 0xe181
movq %rax, 0x8(%rsp)
movl $0xd0, %edi
callq 0xc1d0
movq %rax, %r15
movl $0xd0, %edx
movq %rax, %rdi
xorl %esi, %esi
callq 0xc360
movb (%rbx), %al
movb %al, 0x7(%rsp)
leaq 0x30(%rsp), %r13
movq %r14, %rdi
movq %r13, %rsi
movl $0xf, %edx
callq 0x32f0f
movb $0x0, 0xf(%r13)
movq %r14, %rdi
movq %r13, %rsi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
movq %rbp, %rcx
xorl %eax, %eax
callq 0x315a6
leaq 0x1(%r15), %rdi
movl $0x10, %edx
movq %r13, %rsi
callq 0xc1c0
leaq 0x11(%r15), %rdi
movl $0x40, %edx
movq 0x10(%rsp), %rsi
callq 0xc1c0
leaq 0x51(%r15), %rdi
movl $0x40, %edx
movq 0x18(%rsp), %rsi
callq 0xc1c0
leaq 0x91(%r15), %rdi
movl $0xa, %edx
movq 0x20(%rsp), %rsi
callq 0xc1c0
leaq 0xa8(%r15), %rdi
movl $0x10, %edx
movq 0x80(%rsp), %rsi
callq 0xc1c0
movq %r14, %rdi
callq 0x3287e
shlb $0x4, %r12b
orb $0x3, %r12b
movb %r12b, (%r15)
leaq 0x28(%rsp), %r12
movq %r12, %rdi
callq 0xc820
movq (%r12), %rax
movq %rax, 0xa0(%r15)
movq 0x8(%rsp), %rax
movl 0xc4(%rbx), %esi
testl %esi, %esi
je 0xe7fc
movq %r14, %rdi
callq 0xe181
movq %rax, %r13
incl 0xcc(%rax)
movl 0xc0(%rax), %esi
cmpl 0xb8(%rax), %esi
jne 0xe733
cmpl %esi, 0xbc(%r13)
jne 0xe733
movl %esi, %eax
movq %r13, %r12
jmp 0xe74c
movq %r14, %rdi
callq 0xe181
movq %rax, %r12
movl 0xb8(%r13), %esi
movl 0xc0(%r13), %eax
movq 0x8(%rsp), %rdx
movl 0xcc(%rdx), %ecx
incl %ecx
movl %ecx, 0xcc(%rdx)
movl %eax, 0xc0(%r15)
movl %esi, 0xbc(%r15)
movq $0x0, 0xc4(%r15)
movl %ecx, 0xb8(%r15)
movl %ecx, 0xc0(%r13)
movl %ecx, 0xbc(%r12)
movq %rsp, %rbp
movl %ecx, (%rbp)
movl $0xd0, %r8d
movq %r14, %rdi
movq %rbp, %rsi
movl $0x4, %edx
movq %r15, %rcx
callq 0x313f4
movl 0xb8(%r13), %eax
movl %eax, (%rbp)
movq %rsp, %rbp
movl $0xd0, %r8d
movq %r14, %rdi
movq %rbp, %rsi
movl $0x4, %edx
movq %r13, %rcx
callq 0x313f4
movl 0xb8(%r12), %eax
movl %eax, (%rbp)
movq %rsp, %rsi
movl $0xd0, %r8d
movq %r14, %rdi
movl $0x4, %edx
movq %r12, %rcx
callq 0x313f4
jmp 0xe88e
movl 0xcc(%rax), %ebp
incl %ebp
movl %ebp, 0xcc(%rax)
movl %ebp, 0xbc(%r15)
movl %ebp, 0xc0(%r15)
movl $0x0, 0xc4(%r15)
movl 0xb8(%rbx), %eax
movl %eax, 0xc8(%r15)
movl %ebp, 0xb8(%r15)
movl $0x1, 0xcc(%r15)
movq %rsp, %r12
movl %ebp, (%r12)
movl $0xd0, %r8d
movq %r14, %rdi
movq %r12, %rsi
movl $0x4, %edx
movq %r15, %rcx
callq 0x313f4
movl %ebp, 0xc4(%rbx)
movl 0xb8(%rbx), %eax
movl %eax, (%r12)
movq %rsp, %rsi
movl $0xd0, %r8d
movq %r14, %rdi
movl $0x4, %edx
movq %rbx, %rcx
callq 0x313f4
movq %rbx, %r13
movl 0xc0(%rbx), %esi
testl %esi, %esi
je 0xe9bd
testb $0x10, (%rbx)
jne 0xe9bd
movb 0x7(%rsp), %cl
andb $0x2, %cl
movb (%r15), %al
andb $0x10, %al
orb %cl, %al
jne 0xe9bd
movq %r14, %rdi
callq 0xe181
movq %rax, %r12
movl 0xbc(%rbx), %eax
movl %eax, 0xbc(%r12)
movl 0xb8(%r12), %eax
movq %rsp, %rsi
movl %eax, (%rsi)
movl $0xd0, %r8d
movq %r14, %rdi
movl $0x4, %edx
movq %r12, %rcx
callq 0x313f4
movl 0xbc(%rbx), %esi
testl %esi, %esi
je 0xe936
movq %r14, %rdi
callq 0xe181
movl 0xb8(%r12), %ecx
movl %ecx, 0xc0(%rax)
movl 0xb8(%rax), %ecx
movq %rsp, %rsi
movl %ecx, (%rsi)
movl $0xd0, %r8d
movq %r14, %rdi
movl $0x4, %edx
movq %rax, %rcx
callq 0x313f4
movq 0x8(%rsp), %rcx
movl 0xbc(%rcx), %eax
movl %eax, 0xbc(%rbx)
movl $0x0, 0xc0(%rbx)
movl 0xb8(%rbx), %eax
movl %eax, 0xbc(%rcx)
movl 0xbc(%rbx), %esi
testl %esi, %esi
je 0xe9a2
movq %r14, %rdi
callq 0xe181
movl 0xb8(%rbx), %ecx
movl %ecx, 0xc0(%rax)
movl 0xb8(%rax), %ecx
movq %rsp, %rsi
movl %ecx, (%rsi)
movl $0xd0, %r8d
movq %r14, %rdi
movl $0x4, %edx
movq %rax, %rcx
callq 0x313f4
movl 0xb8(%rbx), %eax
movq %rsp, %rsi
movl %eax, (%rsi)
movl $0xd0, %r8d
movq %r14, %rdi
movl $0x4, %edx
movq %rbx, %rcx
callq 0x313f4
movq %rsp, %rsi
movl $0x0, (%rsi)
movl $0xd0, %r8d
movq %r14, %rdi
movl $0x4, %edx
movq 0x8(%rsp), %r12
movq %r12, %rcx
callq 0x313f4
movq %r14, %rdi
callq 0x3287e
movq %r12, %rdi
callq 0xc640
cmpq %r13, %rbx
je 0xe9fe
movq %rbx, %rdi
callq 0xc640
movq %r13, %rdi
callq 0xc640
movq %r15, %rdi
callq 0xc640
movl $0x1, %eax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq