// File: /workspace/github_c_makefile_star2_O0/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
subq $0x1110, %rsp           # imm = 0x1110
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
cmpl $0x5, -0x8(%rbp)
je 0x1401
movq 0x2c12(%rip), %rax      # 0x3ff8
movq (%rax), %rdi
leaq 0xcd0(%rip), %rsi       # 0x20c0
movb $0x0, %al
callq 0x10b0
movl $0x1, %edi
callq 0x1100
leaq -0x10a0(%rbp), %rdi
xorl %esi, %esi
movl $0x30, %edx
callq 0x1090
movl $0x0, -0x109c(%rbp)
movl $0x1, -0x1098(%rbp)
leaq 0xce8(%rip), %rdi       # 0x2117
leaq 0xceb(%rip), %rsi       # 0x2121
leaq -0x10a0(%rbp), %rdx
leaq -0x10a8(%rbp), %rcx
callq 0x1120
movl %eax, -0x10b4(%rbp)
cmpl $0x0, %eax
je 0x1494
movq 0x2b9d(%rip), %rax      # 0x3ff8
movq (%rax), %rax
movq %rax, -0x10f8(%rbp)
movl -0x10b4(%rbp), %edi
callq 0x1080
movq -0x10f8(%rbp), %rdi
movq %rax, %rdx
leaq 0xca6(%rip), %rsi       # 0x2127
movb $0x0, %al
callq 0x10b0
movl $0x1, -0x4(%rbp)
jmp 0x1734
movq -0x10a8(%rbp), %rax
movq %rax, -0x10b0(%rbp)
cmpq $0x0, -0x10b0(%rbp)
je 0x153a
movq -0x10b0(%rbp), %rax
movl 0x4(%rax), %edi
movq -0x10b0(%rbp), %rax
movl 0x8(%rax), %esi
movq -0x10b0(%rbp), %rax
movl 0xc(%rax), %edx
callq 0x1150
movl %eax, -0x14(%rbp)
cmpl $-0x1, %eax
jne 0x14e9
leaq 0xc56(%rip), %rdi       # 0x2138
callq 0x10d0
jmp 0x1523
movl -0x14(%rbp), %edi
movq -0x10b0(%rbp), %rax
movq 0x18(%rax), %rsi
movq -0x10b0(%rbp), %rax
movl 0x10(%rax), %edx
callq 0x1110
cmpl $-0x1, %eax
jne 0x1521
leaq 0xc35(%rip), %rdi       # 0x2147
callq 0x10d0
movl -0x14(%rbp), %edi
callq 0x10a0
jmp 0x1523
jmp 0x153a
movq -0x10b0(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x10b0(%rbp)
jmp 0x14a2
cmpq $0x0, -0x10b0(%rbp)
jne 0x1568
movq 0x2aad(%rip), %rax      # 0x3ff8
movq (%rax), %rdi
leaq 0xc02(%rip), %rsi       # 0x2157
movb $0x0, %al
callq 0x10b0
movl $0x2, -0x4(%rbp)
jmp 0x1734
movq -0x10b0(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, -0x1108(%rbp)
movq -0x10b0(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0x1260
movl -0x1108(%rbp), %edi
movq %rax, %rsi
leaq -0x10f0(%rbp), %rdx
movl $0x2e, %ecx
callq 0x1030
leaq 0xbc9(%rip), %rdi       # 0x2172
movb $0x0, %al
callq 0x1070
movq -0x10a8(%rbp), %rdi
callq 0x1140
leaq -0x1060(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdx
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rcx
movq -0x10(%rbp), %rax
movq 0x18(%rax), %r8
movq -0x10(%rbp), %rax
movq 0x20(%rax), %r9
leaq 0xba7(%rip), %rsi       # 0x2191
movb $0x0, %al
callq 0x10f0
movl -0x14(%rbp), %eax
movl %eax, -0x1104(%rbp)
leaq -0x1060(%rbp), %rax
movq %rax, -0x1100(%rbp)
leaq -0x1060(%rbp), %rdi
callq 0x1050
movl -0x1104(%rbp), %edi
movq -0x1100(%rbp), %rsi
movq %rax, %rdx
xorl %ecx, %ecx
callq 0x1060
movl %eax, -0x18(%rbp)
cmpl $-0x1, %eax
jne 0x1649
leaq 0xb63(%rip), %rdi       # 0x219d
callq 0x10d0
movl $0x1, %edi
callq 0x1100
movq 0x2988(%rip), %rax      # 0x3fd8
movq (%rax), %rdi
callq 0x10c0
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rsi
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rdx
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rcx
movq -0x10(%rbp), %rax
movq 0x20(%rax), %r8
leaq 0xb23(%rip), %rdi       # 0x21a2
movb $0x0, %al
callq 0x1070
movl -0x14(%rbp), %edi
leaq -0xfc0(%rbp), %rsi
movl $0xf9f, %edx            # imm = 0xF9F
xorl %ecx, %ecx
callq 0x1040
movl %eax, -0x18(%rbp)
cmpl $-0x1, %eax
jne 0x16ba
leaq 0xb61(%rip), %rdi       # 0x220c
callq 0x10d0
movl $0x1, %edi
callq 0x1100
movslq -0x18(%rbp), %rax
movb $0x0, -0xfc0(%rbp,%rax)
leaq -0xfc0(%rbp), %rdi
leaq 0xb3d(%rip), %rsi       # 0x2211
callq 0x1130
cmpq $0x0, %rax
je 0x16f6
leaq -0xfc0(%rbp), %rsi
leaq 0x9cf(%rip), %rdi       # 0x20bc
movb $0x0, %al
callq 0x1070
jmp 0x1725
leaq -0xff0(%rbp), %rdi
leaq -0xfc0(%rbp), %rsi
callq 0x12a0
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rsi
leaq -0xff0(%rbp), %rdx
callq 0x1310
movl -0x14(%rbp), %edi
callq 0x10a0
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x1110, %rsp           # imm = 0x1110
popq %rbp
retq