// File: /workspace/github_c_makefile_star2_O2/MAGI003769[P]EE450-Socket-Project/client.c
// Function: main
int main(int argc, char *argv[]) {

    int sockfd, numbytes;  
    char buf[MAXBUFLEN];
    char *results[5];
    char args_str[100];
    char check[10];
    struct addrinfo hints, *servinfo, *p;
    int rv;
    char s[INET6_ADDRSTRLEN];

    // check whether aguments enough
    if(argc != 5) {
        fprintf(stderr, "usage Error: client function needs 4 arguments <map_id> <node_1> <node_2> <file_size>\n");
        exit(1);
    }

    // check valid arguments or not
    // if(isalpha(argv[0]) != 0) {
    //     fprintf(stderr, "usage Error: MAP ID should be alphabetic.\n");
    //     return 1;
    // }

    // load up address structs with getaddrinfo()
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;

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

    // loop through all the results and connect to the first we can
    for(p = servinfo; p != NULL; p = p->ai_next) {
        if ((sockfd = socket(p->ai_family, p->ai_socktype,
                p->ai_protocol)) == -1) {
            perror("client: socket");
            continue;
        }

        if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
            perror("client: connect");
            close(sockfd);
            continue;
        }

        break;
    }

    if (p == NULL) {
        fprintf(stderr, "client: failed to connect\n");
        return 2;
    }

    inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr),
            s, sizeof s);
    printf("The client is up and running.\n");

    freeaddrinfo(servinfo); // all done with this structure

    // merge args into single string to one-time send
    sprintf(args_str, "%s %s %s %s", argv[1], argv[2], argv[3], argv[4]);

    if ((numbytes = send(sockfd, args_str, strlen(args_str), 0)) == -1) {
        perror("send");
        exit(1);
    }
    fflush(stdout);
    //printf("%s has been sent\n", args_str);

    // for(int i = 1; i <= 4; i++) {
    //     if ((numbytes = send(sockfd, argv[i], strlen(argv[i]), 0)) == -1) {
    //         perror("send");
    //         exit(1);
    //     }
    //     fflush(stdout);
    //     printf("%s has been sent\n", argv[i]);
    // }

    printf("The client has sent query to AWS using TCP: start vertex %s; destination vertex %s; map %s; file size %s\n", argv[2], argv[3], argv[1], argv[4]);

    if((numbytes = recv(sockfd, buf, MAXBUFLEN-1, 0)) == -1) {
        perror("recv");
        exit(1);
    }
    // fflush(stdout);
    // printf("%d \n", numbytes);
    buf[numbytes] = '\0';
    //strncpy(check, buf, 2);
    //printf("debug: check is %s\n", check);
    if(strstr(buf, "No") != NULL) {
        printf("%s\n", buf);
    } else {
        parse_result(results, buf);
        print_result(argv[2], argv[3], results);
    }

    close(sockfd);

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x10a8, %rsp           # imm = 0x10A8
cmpl $0x5, %edi
jne 0x158f
movq %rsi, %rbx
xorps %xmm0, %xmm0
leaq -0xc0(%rbp), %rdx
movaps %xmm0, (%rdx)
movaps %xmm0, 0x20(%rdx)
movaps %xmm0, 0x10(%rdx)
movl $0x1, 0x8(%rdx)
leaq 0xced(%rip), %rdi       # 0x206f
leaq 0xcf0(%rip), %rsi       # 0x2079
leaq -0x30(%rbp), %r15
movq %r15, %rcx
callq 0x1130
testl %eax, %eax
jne 0x1545
leaq 0xcec(%rip), %r12       # 0x2090
leaq 0xcf4(%rip), %r13       # 0x209f
movq (%r15), %r15
testq %r15, %r15
je 0x156f
movl 0x4(%r15), %edi
movl 0x8(%r15), %esi
movl 0xc(%r15), %edx
callq 0x1160
cmpl $-0x1, %eax
je 0x13fa
movl %eax, %r14d
movq 0x18(%r15), %rsi
movl 0x10(%r15), %edx
movl %eax, %edi
callq 0x1110
cmpl $-0x1, %eax
jne 0x1404
movq %r13, %rdi
callq 0x10d0
movl %r14d, %edi
callq 0x10a0
addq $0x28, %r15
jmp 0x13ab
movq %r12, %rdi
callq 0x10d0
jmp 0x13f4
movl 0x4(%r15), %edi
movq 0x18(%r15), %rax
xorl %ecx, %ecx
cmpw $0xa, (%rax)
sete %cl
leaq (%rax,%rcx,4), %rsi
addq $0x4, %rsi
leaq -0x90(%rbp), %rdx
pushq $0x2e
popq %rcx
callq 0x1030
leaq 0xdbf(%rip), %rdi       # 0x21f2
callq 0x1050
movq -0x30(%rbp), %rdi
callq 0x1150
movq 0x8(%rbx), %rdx
movq 0x10(%rbx), %rcx
movq 0x18(%rbx), %r8
movq 0x20(%rbx), %r9
leaq 0xc72(%rip), %rsi       # 0x20ca
leaq -0x130(%rbp), %r15
movq %r15, %rdi
xorl %eax, %eax
callq 0x10f0
movq %r15, %rdi
callq 0x1060
movl %r14d, %edi
movq %r15, %rsi
movq %rax, %rdx
xorl %ecx, %ecx
callq 0x1070
cmpl $-0x1, %eax
je 0x15ad
movq 0x2b47(%rip), %rax      # 0x3fd8
movq (%rax), %rdi
callq 0x10c0
movq 0x8(%rbx), %rcx
movq 0x10(%rbx), %rsi
movq 0x18(%rbx), %rdx
movq 0x20(%rbx), %r8
leaq 0xc2b(%rip), %rdi       # 0x20db
xorl %eax, %eax
callq 0x1080
leaq -0x10d0(%rbp), %rsi
movl $0xf9f, %edx            # imm = 0xF9F
movl %r14d, %edi
xorl %ecx, %ecx
callq 0x1040
cmpl $-0x1, %eax
je 0x15b6
cltq
movb $0x0, -0x10d0(%rbp,%rax)
leaq 0xc63(%rip), %rsi       # 0x214a
leaq -0x10d0(%rbp), %rdi
callq 0x1140
testq %rax, %rax
je 0x1506
leaq -0x10d0(%rbp), %rdi
callq 0x1050
jmp 0x1529
leaq -0x60(%rbp), %r15
leaq -0x10d0(%rbp), %rsi
movq %r15, %rdi
callq 0x1283
movq 0x10(%rbx), %rdi
movq 0x18(%rbx), %rsi
movq %r15, %rdx
callq 0x12b4
movl %r14d, %edi
callq 0x10a0
xorl %eax, %eax
addq $0x10a8, %rsp           # imm = 0x10A8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x2aac(%rip), %rcx      # 0x3ff8
movq (%rcx), %rbx
movl %eax, %edi
callq 0x1090
leaq 0xb22(%rip), %rsi       # 0x207f
movq %rbx, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x10b0
pushq $0x1
popq %rax
jmp 0x1533
movq 0x2a82(%rip), %rax      # 0x3ff8
movq (%rax), %rcx
leaq 0xb2f(%rip), %rdi       # 0x20af
pushq $0x1a
popq %rsi
pushq $0x1
popq %rdx
callq 0x1120
pushq $0x2
jmp 0x156c
movq 0x2a62(%rip), %rax      # 0x3ff8
movq (%rax), %rcx
leaq 0xa78(%rip), %rdi       # 0x2018
pushq $0x56
popq %rsi
pushq $0x1
popq %rdx
callq 0x1120
jmp 0x15c2
leaq 0xb22(%rip), %rdi       # 0x20d6
jmp 0x15bd
leaq 0xb88(%rip), %rdi       # 0x2145
callq 0x10d0
pushq $0x1
popq %rdi
callq 0x1100