// File: renzibei[P]TSProxy/utils.cpp
// Function: sendTSPacket(int, InnerMsg const*, int)
ssize_t sendTSPacket(int fd, const InnerMsg *msg, int isNonBlocking) {
    static TSPacket packetStruct;
    // static InnerMsg msgStruct;
    memset(&packetStruct, 0, sizeof(TSPacket));
    // memset(&msgStruct, 0, sizeof(msgStruct));
    
    
    // msgStruct.cSeq = cSeq;
    // msgStruct.sSeq = sSeq;
    // msgStruct.dataLength = nbyte;
    // memcpy(msgStruct.data, src, nbyte);
    static uint8_t packetBuffer[PACKET_BUFFER_SIZE];
    memset(packetBuffer, 0, PACKET_BUFFER_SIZE);

    ssize_t dataLen = assembleInnerMsg(packetBuffer, sizeof(packetBuffer), msg);
    if (dataLen < 0) {
        LogHelper::log(Warn, "Fail to assemble InnerMsg, retCode: %d", dataLen);
        return dataLen;
    }
    char key[16], random[16], mac[16];
    int keyRet = constants::getKey(key);
    if (keyRet != 0) {
        LogHelper::log(Warn, "Fail to get key");
        return keyRet;
    } 
    int chiperLen = encrypt((char *)(packetStruct.msgData), sizeof(packetStruct.msgData), (const char*)packetBuffer, dataLen, key, random, mac);
    if (chiperLen < 0) {
        LogHelper::log(Warn, "Fail to encrypt when send TSPacket");
        return chiperLen;
    }
    
    packetStruct.contentType = TSPacketContentType;
    packetStruct.tsVersion = TSPacketVersion;
    packetStruct.length = chiperLen + sizeof(random) + sizeof(mac);
    memcpy(packetStruct.random, random, sizeof(random));
    memcpy(packetStruct.mac, mac, sizeof(mac));

    // fprintf(stderr, "when send, key: ");
    // for(int i = 0; i < 16; ++i) {
    //     fprintf(stderr, "%u ", (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");

    dataLen = assembleTSPacket(packetBuffer, sizeof(packetBuffer), &packetStruct);
    if (dataLen < 0) {
        LogHelper::log(Warn, "Fail to assemble TSPacket, retCode: %d", dataLen);
        return dataLen;
    }
    // size_t dataLen = assembleTSPacket(packetBuffer, &packetStruct);
    LogHelper::log(Debug, "sockFd: %d start to write %d bytes", fd, dataLen);
    return writeNBytes(fd, packetBuffer, dataLen, isNonBlocking);
}

// Assembly:
subq $0x68, %rsp
movl %edi, 0x5c(%rsp)
movq %rsi, 0x50(%rsp)
movl %edx, 0x4c(%rsp)
leaq 0x7a048(%rip), %rdi     # 0x87410
xorl %esi, %esi
movl $0x10026, %edx          # imm = 0x10026
callq 0x2140
leaq 0x8a065(%rip), %rdi     # 0x97440
xorl %esi, %esi
movl $0x10000, %edx          # imm = 0x10000
callq 0x2140
movq 0x50(%rsp), %rdx
leaq 0x8a04d(%rip), %rdi     # 0x97440
movl $0x10000, %esi          # imm = 0x10000
callq 0xd040
movq %rax, 0x40(%rsp)
cmpq $0x0, 0x40(%rsp)
jge 0xd431
movq 0x40(%rsp), %rdx
movl $0x1, %edi
leaq 0x393d(%rip), %rsi      # 0x10d58
movb $0x0, %al
callq 0x28f0
movq 0x40(%rsp), %rax
movq %rax, 0x60(%rsp)
jmp 0xd5a2
leaq 0x30(%rsp), %rdi
callq 0xd8c0
movl %eax, 0xc(%rsp)
cmpl $0x0, 0xc(%rsp)
je 0xd468
movl $0x1, %edi
leaq 0x392d(%rip), %rsi      # 0x10d7f
movb $0x0, %al
callq 0x28f0
movslq 0xc(%rsp), %rax
movq %rax, 0x60(%rsp)
jmp 0xd5a2
movq 0x40(%rsp), %rax
movl %eax, %ecx
leaq 0x79f9a(%rip), %rdi     # 0x87410
addq $0x6, %rdi
movl $0x10000, %esi          # imm = 0x10000
leaq 0x89fba(%rip), %rdx     # 0x97440
leaq 0x30(%rsp), %r8
leaq 0x20(%rsp), %r9
leaq 0x10(%rsp), %rax
movq %rax, (%rsp)
callq 0xe940
movl %eax, 0x8(%rsp)
cmpl $0x0, 0x8(%rsp)
jge 0xd4cb
movl $0x1, %edi
leaq 0x38da(%rip), %rsi      # 0x10d8f
movb $0x0, %al
callq 0x28f0
movslq 0x8(%rsp), %rax
movq %rax, 0x60(%rsp)
jmp 0xd5a2
movb $0x17, 0x79f3e(%rip)    # 0x87410
movw $0x303, 0x79f37(%rip)   # imm = 0x303
movslq 0x8(%rsp), %rax
addq $0x10, %rax
addq $0x10, %rax
movw %ax, 0x79f25(%rip)      # 0x87414
movq 0x20(%rsp), %rax
movq %rax, 0x89f1b(%rip)     # 0x97416
movq 0x28(%rsp), %rax
movq %rax, 0x89f17(%rip)     # 0x9741e
movq 0x10(%rsp), %rax
movq %rax, 0x89f13(%rip)     # 0x97426
movq 0x18(%rsp), %rax
movq %rax, 0x89f0f(%rip)     # 0x9742e
leaq 0x89f1a(%rip), %rdi     # 0x97440
movl $0x10000, %esi          # imm = 0x10000
leaq 0x79ede(%rip), %rdx     # 0x87410
callq 0xd1c0
movq %rax, 0x40(%rsp)
cmpq $0x0, 0x40(%rsp)
jge 0xd568
movq 0x40(%rsp), %rdx
movl $0x1, %edi
leaq 0x385d(%rip), %rsi      # 0x10db2
movb $0x0, %al
callq 0x28f0
movq 0x40(%rsp), %rax
movq %rax, 0x60(%rsp)
jmp 0xd5a2
movl 0x5c(%rsp), %edx
movq 0x40(%rsp), %rcx
movl $0x3, %edi
leaq 0x385c(%rip), %rsi      # 0x10dd9
movb $0x0, %al
callq 0x28f0
movl 0x5c(%rsp), %edi
movq 0x40(%rsp), %rdx
movl 0x4c(%rsp), %ecx
leaq 0x89ea8(%rip), %rsi     # 0x97440
callq 0xcb20
movq %rax, 0x60(%rsp)
movq 0x60(%rsp), %rax
addq $0x68, %rsp
retq
nopl (%rax)