// File: /workspace/github_cpp_makefile_star2_O2/LiGaCu[P]Distributed_System_to_Compute_the_Shortest_Path/client.cpp
// Function: main
int main(int argc, char *argv[])
{
    int TCPfd;
    struct addrinfo hints, *servinfo, *p;

    int rv;

    char buf[MAXDATASIZE];int numbytes;
    char mapid; int srcVtxid,dstVtxid,filesize;
    float Tt,Tp;
    int path[11]; float mindistan;

    if (argc != 5) 
    {
        fprintf(stderr,"usage: [map id]  [src Vertex] [dst Vertex] [filesize]\n");
        exit(1);
    }

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;

    if ((rv = getaddrinfo("127.0.0.1", AWS_PORT, &hints, &servinfo)) != 0) 
    {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
        return 1;
    }

    //The following socket connection codes are from Beej's tutorial
    // loop through all the results and connect to the first we can
    for(p = servinfo; p != NULL; p = p->ai_next) 
    {
        if ((TCPfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) 
        {
            perror("client: socket");
            continue;
        }

        if (connect(TCPfd, p->ai_addr, p->ai_addrlen) == -1) 
        {
            close(TCPfd);
            perror("client: connect");
            continue;
        }
        break;
    }
    if (p == NULL) 
    {
        fprintf(stderr, "client: failed to connect\n");
        return 2;
    }
    freeaddrinfo(servinfo); // all done with this structure

    std::cout << "The client is up and running" << "\n" << std::endl;

    //encode the input massage and prepare it for sending
    mapid = argv[1][0];
    srcVtxid = atoi(argv[2]);
    dstVtxid = atoi(argv[3]);
    filesize = atoi(argv[4]);

    buf[0] = mapid;
    memcpy(buf+1, &srcVtxid, sizeof(int));
    memcpy(buf+1+sizeof(int), &dstVtxid, sizeof(int));
    memcpy(buf+1+2*sizeof(int), &filesize, sizeof(int));

    //send the encoded massage to AWS
    if (send(TCPfd, buf, 1+3*sizeof(int), 0) == -1)
    {
        perror("send");
        exit(1);
    }

    //The following massage on the screen means the end of phase 1.
    std::cout << "The client has sent query to AWS using TCP:\n* start vertex " << srcVtxid << ";\n* destination vertex " << dstVtxid << ";\n* map " << mapid
     << ";\n* file size " << filesize << "\n" << std::endl;

    if ((numbytes = recv(TCPfd, buf, MAXDATASIZE-1, 0)) == -1) 
    {
        perror("recv");
        exit(1);
    }
    if(buf[0] == 'y')
    {
        memcpy(&mindistan, buf + 1                  , sizeof(float));
        memcpy(&Tt       , buf + 1 + sizeof(float)  , sizeof(float));
        memcpy(&Tp       , buf + 1 + sizeof(float)*2, sizeof(float));
        memcpy(path      , buf + 1 + sizeof(float)*3, sizeof(path));
        std::cout << "The Client has received results from aws:" <<  std::endl;
        std::cout << "--------------------------------------------------------------------------------" << std::endl;
        std::cout << "Source \tDestination \tMin Length \tTt \t\tTp \t\tDelay" <<  std::endl;
        std::cout << "--------------------------------------------------------------------------------" << std::endl;
        std::cout << srcVtxid << " \t" << dstVtxid << " \t\t" << mindistan << " \t" << Tt << " \t" << Tp << " \t" << (Tt+Tp) << std::endl;
        std::cout << "--------------------------------------------------------------------------------" << std::endl;
        std::cout << "Shortest path: ";
        for (int i =0 ; i< 11; i++)
        {
            if(path[i] == 2333)
                break;
            
            if (i==0)
                std::cout << path[i];
            else
                std::cout << " -- " << path[i];

        }
        std::cout << std::endl;
    }
    else if(buf[0] == '!')
    {
        if(buf[1] == 'm')
        {
            std::cout << "No map id " << mapid << " found" << std::endl;
        }
        else if(buf[1] == 's')
        {
            std::cout << "No Vertex id " << srcVtxid << " found" << std::endl;
        }
        else if(buf[1] == 'd')
        {
            std::cout << "No Vertex id " << dstVtxid << " found" << std::endl;
        }
        else if(buf[1] == 'b')
        {
            std::cout << "Both Vertex id " << srcVtxid << " and Vertex id " << dstVtxid << " not found" << std::endl;
        }
    }

    close(TCPfd);
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x468, %rsp            # imm = 0x468
cmpl $0x5, %edi
jne 0x178b
movq %rsi, %r14
xorps %xmm0, %xmm0
leaq 0x50(%rsp), %rdx
movaps %xmm0, (%rdx)
movaps %xmm0, 0x20(%rdx)
movaps %xmm0, 0x10(%rdx)
movl $0x1, 0x8(%rdx)
leaq 0xd61(%rip), %rdi       # 0x203b
leaq 0xd64(%rip), %rsi       # 0x2045
leaq 0x18(%rsp), %r15
movq %r15, %rcx
callq 0x10e0
testl %eax, %eax
jne 0x1741
leaq 0xd5f(%rip), %r12       # 0x205c
leaq 0xd67(%rip), %r13       # 0x206b
movq (%r15), %r15
testq %r15, %r15
je 0x176b
movl 0x4(%r15), %edi
movl 0x8(%r15), %esi
movl 0xc(%r15), %edx
callq 0x1030
movq %r12, %rdi
cmpl $-0x1, %eax
je 0x1349
movl %eax, %ebx
movq 0x18(%r15), %rsi
movl 0x10(%r15), %edx
movl %eax, %edi
callq 0x1080
cmpl $-0x1, %eax
jne 0x1354
movl %ebx, %edi
callq 0x1160
movq %r13, %rdi
callq 0x1090
addq $0x28, %r15
jmp 0x1304
movq 0x18(%rsp), %rdi
callq 0x10f0
movq 0x2c6b(%rip), %rdi      # 0x3fd0
leaq 0xd2a(%rip), %rsi       # 0x2096
callq 0x10b0
leaq 0xcc1(%rip), %rsi       # 0x2039
movq %rax, %rdi
callq 0x10b0
movq %rax, %rdi
callq 0x1050
movq 0x8(%r14), %rax
movq 0x10(%r14), %rdi
movb (%rax), %r12b
callq 0x1130
movl %eax, %r15d
movq 0x18(%r14), %rdi
callq 0x1130
movl %eax, %ebp
movq 0x20(%r14), %rdi
callq 0x1130
movl %eax, %r13d
leaq 0x80(%rsp), %rsi
movb %r12b, (%rsi)
movl %r15d, 0x1(%rsi)
movl %ebp, 0x5(%rsi)
movl %eax, 0x9(%rsi)
pushq $0xd
popq %rdx
movl %ebx, %edi
xorl %ecx, %ecx
callq 0x1060
cmpq $-0x1, %rax
je 0x17a9
movq 0x2bec(%rip), %r14      # 0x3fd0
leaq 0xccd(%rip), %rsi       # 0x20b8
movq %r14, %rdi
callq 0x10b0
movq %rax, %rdi
movl %r15d, %esi
callq 0x1140
leaq 0xcef(%rip), %rsi       # 0x20f4
movq %rax, %rdi
callq 0x10b0
movq %rax, %rdi
movl %ebp, %esi
callq 0x1140
leaq 0xcee(%rip), %rsi       # 0x210c
movq %rax, %rdi
callq 0x10b0
movsbl %r12b, %r12d
movq %rax, %rdi
movl %r12d, %esi
callq 0x10c0
leaq 0xcd9(%rip), %rsi       # 0x2115
movq %rax, %rdi
callq 0x10b0
movq %rax, %rdi
movl %r13d, %esi
callq 0x1140
leaq 0xbe3(%rip), %rsi       # 0x2039
movq %rax, %rdi
callq 0x10b0
movq %rax, %rdi
callq 0x1050
leaq 0x80(%rsp), %rsi
movl $0x3e7, %edx            # imm = 0x3E7
movl %ebx, %edi
xorl %ecx, %ecx
callq 0x1040
cmpl $-0x1, %eax
je 0x17b2
movzbl 0x80(%rsp), %eax
cmpl $0x21, %eax
je 0x1654
cmpl $0x79, %eax
jne 0x1726
movss 0x81(%rsp), %xmm0
movss %xmm0, 0x14(%rsp)
movss 0x85(%rsp), %xmm0
movss %xmm0, 0x10(%rsp)
movss 0x89(%rsp), %xmm0
movss %xmm0, 0xc(%rsp)
movups 0x8d(%rsp), %xmm0
movaps %xmm0, 0x20(%rsp)
movups 0x9d(%rsp), %xmm0
movaps %xmm0, 0x30(%rsp)
movups 0xa9(%rsp), %xmm0
movups %xmm0, 0x3c(%rsp)
leaq 0xc2f(%rip), %rsi       # 0x2129
movq %r14, %rdi
callq 0x10b0
movq %rax, %rdi
callq 0x1050
leaq 0xc42(%rip), %r12       # 0x2153
movq %r14, %rdi
movq %r12, %rsi
callq 0x10b0
movq %rax, %rdi
callq 0x1050
leaq 0xc79(%rip), %rsi       # 0x21a4
movq %r14, %rdi
callq 0x10b0
movq %rax, %rdi
callq 0x1050
movq %r14, %rdi
movq %r12, %rsi
callq 0x10b0
movq %rax, %rdi
callq 0x1050
movq %r14, %rdi
movl %r15d, %esi
callq 0x1140
leaq 0xc75(%rip), %r15       # 0x21d5
movq %rax, %rdi
movq %r15, %rsi
callq 0x10b0
movq %rax, %rdi
movl %ebp, %esi
callq 0x1140
leaq 0xc5c(%rip), %rsi       # 0x21d8
movq %rax, %rdi
callq 0x10b0
movq %rax, %rdi
movss 0x14(%rsp), %xmm0
callq 0x1070
movq %rax, %rdi
movq %r15, %rsi
callq 0x10b0
movq %rax, %rdi
movss 0x10(%rsp), %xmm0
callq 0x1070
movq %rax, %rdi
movq %r15, %rsi
callq 0x10b0
movq %rax, %rdi
movss 0xc(%rsp), %xmm0
callq 0x1070
movq %rax, %rdi
movq %r15, %rsi
callq 0x10b0
movss 0x10(%rsp), %xmm0
addss 0xc(%rsp), %xmm0
movq %rax, %rdi
callq 0x1070
movq %rax, %rdi
callq 0x1050
movq %r14, %rdi
movq %r12, %rsi
callq 0x10b0
movq %rax, %rdi
callq 0x1050
leaq 0xbd7(%rip), %rsi       # 0x21dc
movq %r14, %rdi
callq 0x10b0
xorl %r12d, %r12d
leaq 0xbd5(%rip), %r15       # 0x21ec
cmpq $0xb, %r12
je 0x171e
movl 0x20(%rsp,%r12,4), %ebp
cmpl $0x91d, %ebp            # imm = 0x91D
je 0x171e
movq %r14, %rdi
testq %r12, %r12
je 0x1648
movq %r14, %rdi
movq %r15, %rsi
callq 0x10b0
movq %rax, %rdi
movl %ebp, %esi
callq 0x1140
incq %r12
jmp 0x1617
movzbl 0x81(%rsp), %eax
cmpl $0x62, %eax
je 0x16d5
cmpl $0x64, %eax
je 0x1694
cmpl $0x73, %eax
je 0x16ae
cmpl $0x6d, %eax
jne 0x1726
movq 0x2955(%rip), %rdi      # 0x3fd0
leaq 0xb6f(%rip), %rsi       # 0x21f1
callq 0x10b0
movq %rax, %rdi
movl %r12d, %esi
callq 0x10c0
jmp 0x16cc
movq 0x2935(%rip), %rdi      # 0x3fd0
leaq 0xb5a(%rip), %rsi       # 0x21fc
callq 0x10b0
movq %rax, %rdi
movl %ebp, %esi
jmp 0x16c7
movq 0x291b(%rip), %rdi      # 0x3fd0
leaq 0xb40(%rip), %rsi       # 0x21fc
callq 0x10b0
movq %rax, %rdi
movl %r15d, %esi
callq 0x1140
leaq 0xb5b(%rip), %rsi       # 0x222e
jmp 0x1713
movq 0x28f4(%rip), %rdi      # 0x3fd0
leaq 0xb27(%rip), %rsi       # 0x220a
callq 0x10b0
movq %rax, %rdi
movl %r15d, %esi
callq 0x1140
leaq 0xb20(%rip), %rsi       # 0x221a
movq %rax, %rdi
callq 0x10b0
movq %rax, %rdi
movl %ebp, %esi
callq 0x1140
leaq 0xb17(%rip), %rsi       # 0x222a
movq %rax, %rdi
callq 0x10b0
movq %rax, %r14
movq %r14, %rdi
callq 0x1050
movl %ebx, %edi
callq 0x1160
xorl %eax, %eax
addq $0x468, %rsp            # imm = 0x468
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x2890(%rip), %rcx      # 0x3fd8
movq (%rcx), %rbx
movl %eax, %edi
callq 0x1100
leaq 0x8f2(%rip), %rsi       # 0x204b
movq %rbx, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x1110
pushq $0x1
popq %rax
jmp 0x172f
movq 0x2866(%rip), %rax      # 0x3fd8
movq (%rax), %rcx
leaq 0x8ff(%rip), %rdi       # 0x207b
pushq $0x1a
popq %rsi
pushq $0x1
popq %rdx
callq 0x1150
pushq $0x2
jmp 0x1768
movq 0x2846(%rip), %rax      # 0x3fd8
movq (%rax), %rcx
leaq 0x868(%rip), %rdi       # 0x2004
pushq $0x36
popq %rsi
pushq $0x1
popq %rdx
callq 0x1150
jmp 0x17be
leaq 0x903(%rip), %rdi       # 0x20b3
jmp 0x17b9
leaq 0x96b(%rip), %rdi       # 0x2124
callq 0x1090
pushq $0x1
popq %rdi
callq 0x10d0