// File: renzibei[P]TSProxy/utils.cpp
// Function: recvTSPacket(int, InnerMsg*, int)
ssize_t recvTSPacket(int fd, InnerMsg *msg, int isNonBlocking) {
    static uint8_t packetBuffer[PACKET_BUFFER_SIZE];
    LogHelper::log(Debug, "sockFd: %d start to read 5bytes", fd);
    ssize_t readRet = readNBytes(fd, packetBuffer, 5, isNonBlocking);
    if (readRet < 0) {
        return readRet;
    }
    uint8_t tsContentType = *packetBuffer;
    if (tsContentType != TSPacketContentType) {
        LogHelper::log(Warn, "content type not right");
        return -1;
    }
    uint16_t msgLen = 0, tsVersion = 0;
    ntoh_copy2bytes(&tsVersion, packetBuffer + 1);
    
    if (tsVersion != TSPacketVersion) {
        LogHelper::log(Warn, "Packet version not equals to tsversion");
        return -2;
    }

    ntoh_copy2bytes(&(msgLen), packetBuffer + 3);
    LogHelper::log(Debug, "sockFd: %d start to read %d bytes", fd, msgLen);
    readRet = readNBytes(fd, packetBuffer + 5, msgLen, isNonBlocking);
    if (readRet < 0) {
        return readRet;
    }
    static TSPacket packetStruct;
    memset(&packetStruct, 0, sizeof(packetStruct));
    int code = disAssembleTSPacket(&packetStruct, packetBuffer, msgLen + 5);
    if (code < 0) {
        LogHelper::log(Warn, "Fail to disassemble TSPacket in recv");
        return code;
    }
    char key[16];
    int keyRet = constants::getKey(key);
    if(keyRet != 0) {
        LogHelper::log(Error, "Fail to get key");
        return -3;
    }

    // fprintf(stderr, "when recv key: ");
    // for(int i = 0; i < 16; ++i) {
    //     fprintf(stderr, "%d ", (uint8_t)key[i]);
    // }
    // fprintf(stderr, "\nrandom: ");
    // for(int i = 0; i < 16; ++i) {
    //     fprintf(stderr, "%u ", (uint8_t)packetStruct.random[i]);
    // }
    // fprintf(stderr, "\nmac: ");
    // for(int i = 0; i < 16; ++i) {
    //     fprintf(stderr, "%u ", (uint8_t)packetStruct.mac[i]);
    // }
    // fprintf(stderr, "\n");

    int textLen = decrypt((char*)packetBuffer, sizeof(packetBuffer), (const char*)packetStruct.msgData, packetStruct.length - 32, key, packetStruct.random, packetStruct.mac);
    if (textLen < 0) {
        LogHelper::log(Warn, "Fail to decrypt when recv ts packet");
        return -4;
    }


    code = disAssembleInnerMsg(msg, packetBuffer, textLen);
    if (code < 0) {
        LogHelper::log(Warn, "Fail to disassemble inner msg in recv");
        return code;
    }
    return 0;
}

// Assembly:
subq $0x58, %rsp
movl %edi, 0x4c(%rsp)
movq %rsi, 0x40(%rsp)
movl %edx, 0x3c(%rsp)
movl 0x4c(%rsp), %edx
movl $0x3, %edi
leaq 0x382b(%rip), %rsi      # 0x10dfc
movb $0x0, %al
callq 0x28f0
movl 0x4c(%rsp), %edi
movl 0x3c(%rsp), %ecx
leaq 0x99e59(%rip), %rsi     # 0xa7440
movl $0x5, %edx
callq 0xca10
movq %rax, 0x30(%rsp)
cmpq $0x0, 0x30(%rsp)
jge 0xd60d
movq 0x30(%rsp), %rax
movq %rax, 0x50(%rsp)
jmp 0xd83b
movb 0x99e2d(%rip), %al      # 0xa7440
movb %al, 0x2f(%rsp)
movzbl 0x2f(%rsp), %eax
cmpl $0x17, %eax
je 0xd642
movl $0x1, %edi
leaq 0x37ef(%rip), %rsi      # 0x10e1c
movb $0x0, %al
callq 0x28f0
movq $-0x1, 0x50(%rsp)
jmp 0xd83b
movw $0x0, 0x2c(%rsp)
movw $0x0, 0x2a(%rsp)
movzwl 0x99dea(%rip), %edi     # 0xa7441
callq 0x2390
movw %ax, 0x2a(%rsp)
movzwl 0x2a(%rsp), %eax
cmpl $0x303, %eax            # imm = 0x303
je 0xd68e
movl $0x1, %edi
leaq 0x37ba(%rip), %rsi      # 0x10e33
movb $0x0, %al
callq 0x28f0
movq $-0x2, 0x50(%rsp)
jmp 0xd83b
movzwl 0x99dae(%rip), %edi     # 0xa7443
callq 0x2390
movw %ax, 0x2c(%rsp)
movl 0x4c(%rsp), %edx
movzwl 0x2c(%rsp), %ecx
movl $0x3, %edi
leaq 0x37a6(%rip), %rsi      # 0x10e5a
movb $0x0, %al
callq 0x28f0
movl 0x4c(%rsp), %edi
movzwl 0x2c(%rsp), %eax
movl %eax, %edx
movl 0x3c(%rsp), %ecx
leaq 0x99d6f(%rip), %rsi     # 0xa7440
addq $0x5, %rsi
callq 0xca10
movq %rax, 0x30(%rsp)
cmpq $0x0, 0x30(%rsp)
jge 0xd6f6
movq 0x30(%rsp), %rax
movq %rax, 0x50(%rsp)
jmp 0xd83b
leaq 0xa9d43(%rip), %rdi     # 0xb7440
xorl %esi, %esi
movl $0x10026, %edx          # imm = 0x10026
callq 0x2140
movzwl 0x2c(%rsp), %eax
addl $0x5, %eax
movslq %eax, %rdx
leaq 0xa9d25(%rip), %rdi     # 0xb7440
leaq 0x99d1e(%rip), %rsi     # 0xa7440
callq 0xcdf0
movl %eax, 0x24(%rsp)
cmpl $0x0, 0x24(%rsp)
jge 0xd754
movl $0x1, %edi
leaq 0x373e(%rip), %rsi      # 0x10e7c
movb $0x0, %al
callq 0x28f0
movslq 0x24(%rsp), %rax
movq %rax, 0x50(%rsp)
jmp 0xd83b
leaq 0x10(%rsp), %rdi
callq 0xd8c0
movl %eax, 0xc(%rsp)
cmpl $0x0, 0xc(%rsp)
je 0xd787
xorl %edi, %edi
leaq 0x360d(%rip), %rsi      # 0x10d7f
movb $0x0, %al
callq 0x28f0
movq $-0x3, 0x50(%rsp)
jmp 0xd83b
movzwl 0xa9cb6(%rip), %ecx     # 0xb7444
subl $0x20, %ecx
leaq 0x99ca8(%rip), %rdi     # 0xa7440
movl $0x10000, %esi          # imm = 0x10000
leaq 0xa9c9c(%rip), %rax     # 0xb7440
movq %rax, %rdx
addq $0x6, %rdx
leaq 0x10(%rsp), %r8
movq %rax, %r9
addq $0x10006, %r9           # imm = 0x10006
addq $0x10016, %rax          # imm = 0x10016
movq %rax, (%rsp)
callq 0xeae0
movl %eax, 0x8(%rsp)
cmpl $0x0, 0x8(%rsp)
jge 0xd7f2
movl $0x1, %edi
leaq 0x36c1(%rip), %rsi      # 0x10ea1
movb $0x0, %al
callq 0x28f0
movq $-0x4, 0x50(%rsp)
jmp 0xd83b
movq 0x40(%rsp), %rdi
movslq 0x8(%rsp), %rdx
leaq 0x99c3d(%rip), %rsi     # 0xa7440
callq 0xcc30
movl %eax, 0x24(%rsp)
cmpl $0x0, 0x24(%rsp)
jge 0xd832
movl $0x1, %edi
leaq 0x36a6(%rip), %rsi      # 0x10ec5
movb $0x0, %al
callq 0x28f0
movslq 0x24(%rsp), %rax
movq %rax, 0x50(%rsp)
jmp 0xd83b
movq $0x0, 0x50(%rsp)
movq 0x50(%rsp), %rax
addq $0x58, %rsp
retq
nopw %cs:(%rax,%rax)