// File: /workspace/github_c_makefile_star2_O2/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, %r13
movq %rdi, %r14
movb 0x88(%rsp), %r12b
callq 0xd515
movq %rax, %rbx
movq %r14, %rdi
xorl %esi, %esi
callq 0xd515
movq %rax, 0x8(%rsp)
movl $0xd0, %edi
callq 0xc1f0
movq %rax, %r15
movl $0xd0, %edx
movq %rax, %rdi
xorl %esi, %esi
callq 0xc370
movb (%rbx), %al
movb %al, 0x7(%rsp)
leaq 0x30(%rsp), %rbp
pushq $0xf
popq %rdx
movq %r14, %rdi
movq %rbp, %rsi
callq 0x2bc94
movb $0x0, 0xf(%rbp)
movq %r14, %rdi
movq %rbp, %rsi
movq %r13, %rdx
xorl %ecx, %ecx
callq 0xd86c
leaq 0x1(%r15), %rdi
pushq $0x10
popq %r13
movq %rbp, %rsi
movq %r13, %rdx
callq 0xc1e0
leaq 0x11(%r15), %rdi
pushq $0x40
popq %rbp
movq 0x10(%rsp), %rsi
movq %rbp, %rdx
callq 0xc1e0
leaq 0x51(%r15), %rdi
movq 0x18(%rsp), %rsi
movq %rbp, %rdx
callq 0xc1e0
leaq 0x91(%r15), %rdi
pushq $0xa
popq %rdx
movq 0x20(%rsp), %rsi
callq 0xc1e0
leaq 0xa8(%r15), %rdi
movq 0x80(%rsp), %rsi
movq %r13, %rdx
callq 0xc1e0
movq %r14, %rdi
callq 0x2b666
shlb $0x4, %r12b
orb $0x3, %r12b
movb %r12b, (%r15)
leaq 0x28(%rsp), %r12
movq %r12, %rdi
callq 0xc850
movq (%r12), %rax
movq %rax, 0xa0(%r15)
movl 0xc4(%rbx), %esi
testl %esi, %esi
je 0xda7c
movq 0x8(%rsp), %rbp
movq %r14, %rdi
callq 0xd515
movq %rax, %r13
incl 0xcc(%rax)
movl 0xc0(%rax), %esi
cmpl 0xb8(%rax), %esi
jne 0xda04
cmpl %esi, 0xbc(%r13)
jne 0xda04
movl %esi, %ecx
movq %r13, %r12
jmp 0xda1d
movq %r14, %rdi
callq 0xd515
movq %rax, %r12
movl 0xb8(%r13), %esi
movl 0xc0(%r13), %ecx
movl 0xcc(%rbp), %eax
incl %eax
movl %eax, 0xcc(%rbp)
movl %ecx, 0xc0(%r15)
movl %esi, 0xbc(%r15)
andq $0x0, 0xc4(%r15)
movl %eax, 0xb8(%r15)
movl %eax, 0xc0(%r13)
movl %eax, 0xbc(%r12)
movq %r14, %rdi
movl %eax, %esi
movq %r15, %rdx
xorl %ecx, %ecx
callq 0xd674
movl 0xb8(%r13), %esi
movq %r14, %rdi
movq %r13, %rdx
xorl %ecx, %ecx
callq 0xd674
jmp 0xdae4
movq 0x8(%rsp), %rax
movl 0xcc(%rax), %ebp
incl %ebp
movl %ebp, 0xcc(%rax)
movl %ebp, 0xbc(%r15)
movl %ebp, 0xc0(%r15)
andl $0x0, 0xc4(%r15)
movl 0xb8(%rbx), %eax
movl %eax, 0xc8(%r15)
movl %ebp, 0xb8(%r15)
movl $0x1, 0xcc(%r15)
movq %r14, %rdi
movl %ebp, %esi
movq %r15, %rdx
xorl %ecx, %ecx
callq 0xd674
movl %ebp, 0xc4(%rbx)
movq %rbx, %r12
movq %rbx, %r13
movq 0x8(%rsp), %rbp
movl 0xb8(%r12), %esi
movq %r14, %rdi
movq %r12, %rdx
xorl %ecx, %ecx
callq 0xd674
movl 0xc0(%rbx), %esi
testl %esi, %esi
je 0xdbea
testb $0x10, (%rbx)
jne 0xdbea
movb 0x7(%rsp), %cl
andb $0x2, %cl
movb (%r15), %al
andb $0x10, %al
orb %cl, %al
jne 0xdbea
movq %r14, %rdi
callq 0xd515
movq %rax, %r12
movl 0xbc(%rbx), %eax
movl %eax, 0xbc(%r12)
movl 0xb8(%r12), %esi
movq %r14, %rdi
movq %r12, %rdx
xorl %ecx, %ecx
callq 0xd674
movl 0xbc(%rbx), %esi
testl %esi, %esi
je 0xdb85
movq %r14, %rdi
callq 0xd515
movl 0xb8(%r12), %ecx
movl %ecx, 0xc0(%rax)
movl 0xb8(%rax), %esi
movq %r14, %rdi
movq %rax, %rdx
xorl %ecx, %ecx
callq 0xd674
movl 0xbc(%rbp), %eax
movl %eax, 0xbc(%rbx)
andl $0x0, 0xc0(%rbx)
movl 0xb8(%rbx), %esi
movl %esi, 0xbc(%rbp)
movl 0xbc(%rbx), %eax
testl %eax, %eax
je 0xdbdd
movq %r14, %rdi
movl %eax, %esi
callq 0xd515
movl 0xb8(%rbx), %ecx
movl %ecx, 0xc0(%rax)
movl 0xb8(%rax), %esi
movq %r14, %rdi
movq %rax, %rdx
xorl %ecx, %ecx
callq 0xd674
movl 0xb8(%rbx), %esi
movq %r14, %rdi
movq %rbx, %rdx
xorl %ecx, %ecx
callq 0xd674
movq %r14, %rdi
xorl %esi, %esi
movq %rbp, %rdx
xorl %ecx, %ecx
callq 0xd674
movq %r14, %rdi
callq 0x2b666
movq %rbp, %rdi
callq 0xc660
cmpq %r13, %rbx
je 0xdc16
movq %rbx, %rdi
callq 0xc660
movq %r13, %rdi
callq 0xc660
movq %r15, %rdi
callq 0xc660
pushq $0x1
popq %rax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq