// File: /workspace/github_c_makefile_star2_O3/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 0x1629
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 0xc2b(%rip), %rdi       # 0x206f
leaq 0xc2e(%rip), %rsi       # 0x2079
leaq -0x30(%rbp), %rcx
callq 0x1130
testl %eax, %eax
jne 0x161b
movq -0x30(%rbp), %r13
testq %r13, %r13
je 0x160f
leaq 0xc20(%rip), %r15       # 0x2090
leaq 0xc28(%rip), %r12       # 0x209f
movl 0x4(%r13), %edi
movl 0x8(%r13), %esi
movl 0xc(%r13), %edx
callq 0x1160
cmpl $-0x1, %eax
je 0x14c2
movl %eax, %r14d
movq 0x18(%r13), %rsi
movl 0x10(%r13), %edx
movl %eax, %edi
callq 0x1110
cmpl $-0x1, %eax
jne 0x14cc
movq %r12, %rdi
callq 0x10d0
movl %r14d, %edi
callq 0x10a0
movq 0x28(%r13), %r13
testq %r13, %r13
jne 0x1477
jmp 0x160f
movq %r15, %rdi
callq 0x10d0
jmp 0x14b4
movl 0x4(%r13), %edi
movq 0x18(%r13), %rax
xorl %ecx, %ecx
cmpw $0xa, (%rax)
sete %cl
leaq (%rax,%rcx,4), %rsi
addq $0x4, %rsi
leaq -0x90(%rbp), %rdx
movl $0x2e, %ecx
callq 0x1030
leaq 0xcf5(%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 0xba8(%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 0x162e
movq 0x2a7d(%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 0xb61(%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 0x1633
cltq
movb $0x0, -0x10d0(%rbp,%rax)
leaq 0xb99(%rip), %rsi       # 0x214a
leaq -0x10d0(%rbp), %rdi
callq 0x1140
testq %rax, %rax
je 0x15d0
leaq -0x10d0(%rbp), %rdi
callq 0x1050
jmp 0x15f3
leaq -0x60(%rbp), %r15
leaq -0x10d0(%rbp), %rsi
movq %r15, %rdi
callq 0x1333
movq 0x10(%rbx), %rdi
movq 0x18(%rbx), %rsi
movq %r15, %rdx
callq 0x1376
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
callq 0x1208
movl $0x2, %eax
jmp 0x15fd
movl %eax, %edi
callq 0x11a8
movl $0x1, %eax
jmp 0x15fd
callq 0x1180
callq 0x11f0
callq 0x11d8