// File: 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
movq %rsp, %rbp
subq $0x4b0, %rsp            # imm = 0x4B0
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
cmpl $0x5, -0x8(%rbp)
je 0x1301
movq 0x2cf2(%rip), %rax      # 0x3fd8
movq (%rax), %rdi
leaq 0xd14(%rip), %rsi       # 0x2004
movb $0x0, %al
callq 0x1130
movl $0x1, %edi
callq 0x10f0
leaq -0x48(%rbp), %rdi
xorl %esi, %esi
movl $0x30, %edx
callq 0x1060
movl $0x0, -0x44(%rbp)
movl $0x1, -0x40(%rbp)
leaq 0xd15(%rip), %rdi       # 0x203b
leaq 0xd18(%rip), %rsi       # 0x2045
leaq -0x48(%rbp), %rdx
leaq -0x50(%rbp), %rcx
callq 0x1100
movl %eax, -0x5c(%rbp)
cmpl $0x0, %eax
je 0x137f
movq 0x2c8f(%rip), %rax      # 0x3fd8
movq (%rax), %rax
movq %rax, -0x4b0(%rbp)
movl -0x5c(%rbp), %edi
callq 0x1120
movq -0x4b0(%rbp), %rdi
movq %rax, %rdx
leaq 0xcdf(%rip), %rsi       # 0x204b
movb $0x0, %al
callq 0x1130
movl $0x1, -0x4(%rbp)
jmp 0x19d2
movq -0x50(%rbp), %rax
movq %rax, -0x58(%rbp)
cmpq $0x0, -0x58(%rbp)
je 0x1400
movq -0x58(%rbp), %rax
movl 0x4(%rax), %edi
movq -0x58(%rbp), %rax
movl 0x8(%rax), %esi
movq -0x58(%rbp), %rax
movl 0xc(%rax), %edx
callq 0x1030
movl %eax, -0x14(%rbp)
cmpl $-0x1, %eax
jne 0x13be
leaq 0xca5(%rip), %rdi       # 0x205c
callq 0x10a0
jmp 0x13f2
movl -0x14(%rbp), %edi
movq -0x58(%rbp), %rax
movq 0x18(%rax), %rsi
movq -0x58(%rbp), %rax
movl 0x10(%rax), %edx
callq 0x1090
cmpl $-0x1, %eax
jne 0x13f0
movl -0x14(%rbp), %edi
callq 0x1170
leaq 0xc82(%rip), %rdi       # 0x206b
callq 0x10a0
jmp 0x13f2
jmp 0x1400
movq -0x58(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x58(%rbp)
jmp 0x1387
cmpq $0x0, -0x58(%rbp)
jne 0x142b
movq 0x2bca(%rip), %rax      # 0x3fd8
movq (%rax), %rdi
leaq 0xc63(%rip), %rsi       # 0x207b
movb $0x0, %al
callq 0x1130
movl $0x2, -0x4(%rbp)
jmp 0x19d2
movq -0x50(%rbp), %rdi
callq 0x1110
movq 0x2b95(%rip), %rdi      # 0x3fd0
leaq 0xc54(%rip), %rsi       # 0x2096
callq 0x10c0
movq %rax, %rdi
leaq 0xbe8(%rip), %rsi       # 0x2039
callq 0x10c0
movq %rax, %rdi
movq 0x2b60(%rip), %rsi      # 0x3fc0
callq 0x10d0
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movb (%rax), %al
movb %al, -0x455(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x1150
movl %eax, -0x45c(%rbp)
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0x1150
movl %eax, -0x460(%rbp)
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0x1150
movl %eax, -0x464(%rbp)
movb -0x455(%rbp), %al
movb %al, -0x450(%rbp)
movl -0x45c(%rbp), %eax
movl %eax, -0x44f(%rbp)
movl -0x460(%rbp), %eax
movl %eax, -0x44b(%rbp)
movl -0x464(%rbp), %eax
movl %eax, -0x447(%rbp)
movl -0x14(%rbp), %edi
leaq -0x450(%rbp), %rsi
movl $0xd, %edx
xorl %ecx, %ecx
callq 0x1050
cmpq $-0x1, %rax
jne 0x1510
leaq 0xbb2(%rip), %rdi       # 0x20b3
callq 0x10a0
movl $0x1, %edi
callq 0x10f0
movq 0x2ab9(%rip), %rdi      # 0x3fd0
leaq 0xb9a(%rip), %rsi       # 0x20b8
callq 0x10c0
movq %rax, %rdi
movl -0x45c(%rbp), %esi
callq 0x1160
movq %rax, %rdi
leaq 0xbb9(%rip), %rsi       # 0x20f4
callq 0x10c0
movq %rax, %rdi
movl -0x460(%rbp), %esi
callq 0x1160
movq %rax, %rdi
leaq 0xbb4(%rip), %rsi       # 0x210c
callq 0x10c0
movq %rax, %rdi
movsbl -0x455(%rbp), %esi
callq 0x10e0
movq %rax, %rdi
leaq 0xb9f(%rip), %rsi       # 0x2115
callq 0x10c0
movq %rax, %rdi
movl -0x464(%rbp), %esi
callq 0x1160
movq %rax, %rdi
leaq 0xaa6(%rip), %rsi       # 0x2039
callq 0x10c0
movq %rax, %rdi
movq 0x2a1e(%rip), %rsi      # 0x3fc0
callq 0x10d0
movl -0x14(%rbp), %edi
leaq -0x450(%rbp), %rsi
movl $0x3e7, %edx            # imm = 0x3E7
xorl %ecx, %ecx
callq 0x1040
movl %eax, -0x454(%rbp)
cmpl $-0x1, %eax
jne 0x15de
leaq 0xb55(%rip), %rdi       # 0x2124
callq 0x10a0
movl $0x1, %edi
callq 0x10f0
movsbl -0x450(%rbp), %eax
cmpl $0x79, %eax
jne 0x1853
movl -0x44f(%rbp), %eax
movl %eax, -0x4a4(%rbp)
movl -0x44b(%rbp), %eax
movl %eax, -0x468(%rbp)
movl -0x447(%rbp), %eax
movl %eax, -0x46c(%rbp)
leaq -0x4a0(%rbp), %rdi
leaq -0x450(%rbp), %rsi
addq $0x1, %rsi
addq $0xc, %rsi
movl $0x2c, %edx
callq 0x1080
movq 0x2997(%rip), %rdi      # 0x3fd0
leaq 0xae9(%rip), %rsi       # 0x2129
callq 0x10c0
movq %rax, %rdi
movq 0x2971(%rip), %rsi      # 0x3fc0
callq 0x10d0
movq 0x2975(%rip), %rdi      # 0x3fd0
leaq 0xaf1(%rip), %rsi       # 0x2153
callq 0x10c0
movq %rax, %rdi
movq 0x294f(%rip), %rsi      # 0x3fc0
callq 0x10d0
movq 0x2953(%rip), %rdi      # 0x3fd0
leaq 0xb20(%rip), %rsi       # 0x21a4
callq 0x10c0
movq %rax, %rdi
movq 0x292d(%rip), %rsi      # 0x3fc0
callq 0x10d0
movq 0x2931(%rip), %rdi      # 0x3fd0
leaq 0xaad(%rip), %rsi       # 0x2153
callq 0x10c0
movq %rax, %rdi
movq 0x290b(%rip), %rsi      # 0x3fc0
callq 0x10d0
movl -0x45c(%rbp), %esi
movq 0x2909(%rip), %rdi      # 0x3fd0
callq 0x1160
movq %rax, %rdi
leaq 0xaff(%rip), %rsi       # 0x21d5
callq 0x10c0
movq %rax, %rdi
movl -0x460(%rbp), %esi
callq 0x1160
movq %rax, %rdi
leaq 0xae5(%rip), %rsi       # 0x21d8
callq 0x10c0
movq %rax, %rdi
movss -0x4a4(%rbp), %xmm0
callq 0x1070
movq %rax, %rdi
leaq 0xac3(%rip), %rsi       # 0x21d5
callq 0x10c0
movq %rax, %rdi
movss -0x468(%rbp), %xmm0
callq 0x1070
movq %rax, %rdi
leaq 0xaa4(%rip), %rsi       # 0x21d5
callq 0x10c0
movq %rax, %rdi
movss -0x46c(%rbp), %xmm0
callq 0x1070
movq %rax, %rdi
leaq 0xa85(%rip), %rsi       # 0x21d5
callq 0x10c0
movq %rax, %rdi
movss -0x468(%rbp), %xmm0
addss -0x46c(%rbp), %xmm0
callq 0x1070
movq %rax, %rdi
movq 0x2849(%rip), %rsi      # 0x3fc0
callq 0x10d0
movq 0x284d(%rip), %rdi      # 0x3fd0
leaq 0x9c9(%rip), %rsi       # 0x2153
callq 0x10c0
movq %rax, %rdi
movq 0x2827(%rip), %rsi      # 0x3fc0
callq 0x10d0
movq 0x282b(%rip), %rdi      # 0x3fd0
leaq 0xa30(%rip), %rsi       # 0x21dc
callq 0x10c0
movl $0x0, -0x4a8(%rbp)
cmpl $0xb, -0x4a8(%rbp)
jge 0x183b
movslq -0x4a8(%rbp), %rax
cmpl $0x91d, -0x4a0(%rbp,%rax,4) # imm = 0x91D
jne 0x17da
jmp 0x183b
cmpl $0x0, -0x4a8(%rbp)
jne 0x17ff
movslq -0x4a8(%rbp), %rax
movl -0x4a0(%rbp,%rax,4), %esi
movq 0x27d8(%rip), %rdi      # 0x3fd0
callq 0x1160
jmp 0x1828
movq 0x27ca(%rip), %rdi      # 0x3fd0
leaq 0x9df(%rip), %rsi       # 0x21ec
callq 0x10c0
movq %rax, %rdi
movslq -0x4a8(%rbp), %rax
movl -0x4a0(%rbp,%rax,4), %esi
callq 0x1160
jmp 0x182a
movl -0x4a8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4a8(%rbp)
jmp 0x17bb
movq 0x278e(%rip), %rdi      # 0x3fd0
movq 0x2777(%rip), %rsi      # 0x3fc0
callq 0x10d0
jmp 0x19c3
movsbl -0x450(%rbp), %eax
cmpl $0x21, %eax
jne 0x19c1
movsbl -0x44f(%rbp), %eax
cmpl $0x6d, %eax
jne 0x18b4
movq 0x275a(%rip), %rdi      # 0x3fd0
leaq 0x974(%rip), %rsi       # 0x21f1
callq 0x10c0
movq %rax, %rdi
movsbl -0x455(%rbp), %esi
callq 0x10e0
movq %rax, %rdi
leaq 0x993(%rip), %rsi       # 0x222e
callq 0x10c0
movq %rax, %rdi
movq 0x2716(%rip), %rsi      # 0x3fc0
callq 0x10d0
jmp 0x19bf
movsbl -0x44f(%rbp), %eax
cmpl $0x73, %eax
jne 0x1904
movq 0x2709(%rip), %rdi      # 0x3fd0
leaq 0x92e(%rip), %rsi       # 0x21fc
callq 0x10c0
movq %rax, %rdi
movl -0x45c(%rbp), %esi
callq 0x1160
movq %rax, %rdi
leaq 0x943(%rip), %rsi       # 0x222e
callq 0x10c0
movq %rax, %rdi
movq 0x26c6(%rip), %rsi      # 0x3fc0
callq 0x10d0
jmp 0x19bd
movsbl -0x44f(%rbp), %eax
cmpl $0x64, %eax
jne 0x1951
movq 0x26b9(%rip), %rdi      # 0x3fd0
leaq 0x8de(%rip), %rsi       # 0x21fc
callq 0x10c0
movq %rax, %rdi
movl -0x460(%rbp), %esi
callq 0x1160
movq %rax, %rdi
leaq 0x8f3(%rip), %rsi       # 0x222e
callq 0x10c0
movq %rax, %rdi
movq 0x2676(%rip), %rsi      # 0x3fc0
callq 0x10d0
jmp 0x19bb
movsbl -0x44f(%rbp), %eax
cmpl $0x62, %eax
jne 0x19b9
movq 0x266c(%rip), %rdi      # 0x3fd0
leaq 0x89f(%rip), %rsi       # 0x220a
callq 0x10c0
movq %rax, %rdi
movl -0x45c(%rbp), %esi
callq 0x1160
movq %rax, %rdi
leaq 0x892(%rip), %rsi       # 0x221a
callq 0x10c0
movq %rax, %rdi
movl -0x460(%rbp), %esi
callq 0x1160
movq %rax, %rdi
leaq 0x885(%rip), %rsi       # 0x222a
callq 0x10c0
movq %rax, %rdi
movq 0x260c(%rip), %rsi      # 0x3fc0
callq 0x10d0
jmp 0x19bb
jmp 0x19bd
jmp 0x19bf
jmp 0x19c1
jmp 0x19c3
movl -0x14(%rbp), %edi
callq 0x1170
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x4b0, %rsp            # imm = 0x4B0
popq %rbp
retq