// File: /workspace/github_cpp_makefile_star2_O2/LiGaCu[P]Distributed_System_to_Compute_the_Shortest_Path/serverC.cpp
// Function: main
int main(void)
{
    int selffd;
    struct addrinfo hints, *servinfo;
    int rv;

    char buf[MAXDATASIZE];int numbytes;
    std::string stringbuff;
    int srcVtxid, dstVtxid, filesize; char mapid;
    float Pspeed; int Tspeed;
    float Tt,Tp;
    int path[11]; float mindistan = inf_dis;

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4
    hints.ai_socktype = SOCK_DGRAM;
    if ((rv = getaddrinfo("127.0.0.1", CUDPPORT, &hints, &servinfo)) != 0) 
    {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
        return 1;
    }
    selffd = getUDPsockandbind(servinfo);
    freeaddrinfo(servinfo);

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4
    hints.ai_socktype = SOCK_DGRAM;
    if ((rv = getaddrinfo("127.0.0.1", AWSUDPPORT, &hints, &servinfo)) != 0) 
    {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
        return 1;
    }

    std::cout << "The server C is up and running using UDP on port " << CUDPPORT << "\n" << std::endl;

    while(1)
    {
        if ((numbytes = recvfrom(selffd, buf, MAXDATASIZE-1 , 0, (struct sockaddr *) NULL, NULL)) == -1) 
        {
            perror("recvfrom");
            exit(1);
        }
        memcpy(&srcVtxid, buf, sizeof(int));
        memcpy(&dstVtxid, buf+sizeof(int), sizeof(int));
        memcpy(&filesize, buf+2*sizeof(int), sizeof(int));
        memcpy(&mapid, buf+3*sizeof(int), sizeof(char));

        stringbuff.assign(buf + 3*sizeof(int) + sizeof(char), numbytes - 3*sizeof(int) - sizeof(char));

        std::istringstream tokenStream (stringbuff);
        std::string Pspeedbuf, Tspeedbuf;
        std::getline(tokenStream,Pspeedbuf);
        std::getline(tokenStream,Tspeedbuf);
        Pspeed = atof(Pspeedbuf.c_str());
        Tspeed = atoi(Tspeedbuf.c_str());

        std::cout << "The Server C has received data for calculation:\n" << "* Propagation Speed: " << Pspeed << " km/s;\n* Transmission Speed: " << Tspeed 
        << " KB/s;\n* Map ID: " << mapid << ";\n* Source ID: " << srcVtxid << ";\n* Destination ID: " << dstVtxid << ";\n" << std::endl;

        // find the shortest path and its length and store them in path and mindistan respectively.
        searchpath(tokenStream, srcVtxid, dstVtxid, path, &mindistan); 

        Tt = (float) filesize/ (float) Tspeed;
        Tp = mindistan/Pspeed;

        std::cout << "The Server C has finished the calculation:\n" <<  "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 << "\nShortest Distance: " << mindistan << " km\nTransmission Delay: " << Tt << " s\nPropagation Delay: " << Tp << " s\n" << std::endl;

        memcpy(buf                  , &mindistan, sizeof(float));
        memcpy(buf + sizeof(float)  , &Tt       , sizeof(float));
        memcpy(buf + sizeof(float)*2, &Tp       , sizeof(float));
        memcpy(buf + sizeof(float)*3, path      , sizeof(path));
        if ((numbytes = sendto(selffd, buf, sizeof(float)*3 + sizeof(path), 0, servinfo->ai_addr, servinfo->ai_addrlen)) == -1) 
        {
            perror("talker: sendto");
            exit(1);
        }
        std::cout << "The Server C has finished sending the output to AWS\n" << std::endl ;
    }

    close(selffd);
    freeaddrinfo(servinfo);
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x668, %rsp            # imm = 0x668
leaq 0x80(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb $0x0, (%rax)
movl $0x4cbebc20, 0x4(%rsp)  # imm = 0x4CBEBC20
xorps %xmm0, %xmm0
leaq 0xd0(%rsp), %rdx
movaps %xmm0, (%rdx)
movaps %xmm0, 0x10(%rdx)
movaps %xmm0, 0x20(%rdx)
movl $0x2, 0x8(%rdx)
leaq 0xc7b(%rip), %rdi       # 0x3008
leaq 0xc7e(%rip), %rsi       # 0x3012
leaq 0x8(%rsp), %rcx
callq 0x2130
testl %eax, %eax
jne 0x23f2
movq 0x8(%rsp), %rdi
callq 0x2823
movl %eax, %ebx
leaq 0x8(%rsp), %r14
movq (%r14), %rdi
callq 0x2140
xorps %xmm0, %xmm0
leaq 0xd0(%rsp), %rdx
movaps %xmm0, (%rdx)
movaps %xmm0, 0x20(%rdx)
movaps %xmm0, 0x10(%rdx)
movl $0x2, 0x8(%rdx)
leaq 0xc29(%rip), %rdi       # 0x3008
leaq 0xc43(%rip), %rsi       # 0x3029
movq %r14, %rcx
callq 0x2130
testl %eax, %eax
je 0x2436
movq 0x2bdf(%rip), %rcx      # 0x4fd8
movq (%rcx), %rbx
movl %eax, %edi
callq 0x2160
leaq 0xc0e(%rip), %rsi       # 0x3018
movq %rbx, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x2170
leaq 0x70(%rsp), %rdi
callq 0x2070
pushq $0x1
popq %rax
addq $0x668, %rsp            # imm = 0x668
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x2b93(%rip), %r14      # 0x4fd0
leaq 0xbeb(%rip), %rsi       # 0x302f
movq %r14, %rdi
callq 0x20e0
leaq 0xbbf(%rip), %rsi       # 0x3012
movq %rax, %rdi
callq 0x20e0
leaq 0xcd1(%rip), %rsi       # 0x3133
movq %rax, %rdi
callq 0x20e0
movq %rax, %rdi
callq 0x2090
leaq 0x100(%rsp), %rbp
movl $0x3e7, %edx            # imm = 0x3E7
movl %ebx, %edi
leaq 0x280(%rsp), %rsi
xorl %ecx, %ecx
xorl %r8d, %r8d
xorl %r9d, %r9d
callq 0x20b0
cmpl $-0x1, %eax
je 0x27c5
movl 0x280(%rsp), %r15d
movl 0x284(%rsp), %r12d
movl 0x288(%rsp), %ecx
movl %ecx, 0x10(%rsp)
movb 0x28c(%rsp), %r13b
movslq %eax, %rdx
addq $-0xd, %rdx
leaq 0x70(%rsp), %rdi
leaq 0x28d(%rsp), %rsi
callq 0x2150
movq %rbp, %rdi
leaq 0x70(%rsp), %rsi
pushq $0x8
popq %rdx
callq 0x21a0
leaq 0x60(%rsp), %rax
movq %rax, 0x50(%rsp)
andq $0x0, 0x58(%rsp)
xorl %ecx, %ecx
movb %cl, 0x60(%rsp)
leaq 0x40(%rsp), %rax
movq %rax, 0x30(%rsp)
andq $0x0, 0x38(%rsp)
movb %cl, 0x40(%rsp)
movq %rbp, %rdi
leaq 0x50(%rsp), %rsi
callq 0x2050
leaq 0x100(%rsp), %rdi
leaq 0x30(%rsp), %rsi
callq 0x2050
movq 0x50(%rsp), %rdi
callq 0x2120
movsd %xmm0, 0x20(%rsp)
movq 0x30(%rsp), %rdi
callq 0x2190
movl %eax, %ebp
movq %r14, %rdi
leaq 0xb10(%rip), %rsi       # 0x306a
callq 0x20e0
movq %rax, %rdi
leaq 0xb32(%rip), %rsi       # 0x309b
callq 0x20e0
cvtsd2ss 0x20(%rsp), %xmm0
movq %rax, %rdi
movaps %xmm0, 0x90(%rsp)
callq 0x20a0
movq %rax, %rdi
leaq 0xb23(%rip), %rsi       # 0x30b1
callq 0x20e0
movq %rax, %rdi
movl %ebp, %esi
callq 0x21b0
movq %rax, %rdi
leaq 0xb28(%rip), %rsi       # 0x30cf
callq 0x20e0
movsbl %r13b, %esi
movq %rax, %rdi
callq 0x2100
movq %rax, %rdi
leaq 0xb1f(%rip), %rsi       # 0x30e1
callq 0x20e0
movq %rax, %rdi
movl %r15d, %esi
callq 0x21b0
movq %rax, %rdi
leaq 0xb15(%rip), %rsi       # 0x30f1
callq 0x20e0
movq %rax, %rdi
movl %r12d, %esi
callq 0x21b0
movq %rax, %rdi
leaq 0xb10(%rip), %rsi       # 0x3106
callq 0x20e0
movq %rax, %rdi
callq 0x2090
leaq 0x100(%rsp), %rdi
movl %r15d, %esi
movl %r12d, %edx
leaq 0xa0(%rsp), %rcx
leaq 0x4(%rsp), %r8
callq 0x28f6
movss 0x4(%rsp), %xmm0
movaps %xmm0, 0x20(%rsp)
movq %r14, %rdi
leaq 0xad1(%rip), %rsi       # 0x3109
callq 0x20e0
movq %rax, %rdi
leaq 0xaee(%rip), %rsi       # 0x3135
callq 0x20e0
cvtsi2ssl 0x10(%rsp), %xmm1
cvtsi2ss %ebp, %xmm0
unpcklps 0x20(%rsp), %xmm1       # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
unpcklps 0x90(%rsp), %xmm0       # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
divps %xmm0, %xmm1
movaps %xmm1, 0x10(%rsp)
xorl %r15d, %r15d
cmpq $0xb, %r15
je 0x26aa
movl 0xa0(%rsp,%r15,4), %ebp
cmpl $0x91d, %ebp            # imm = 0x91D
je 0x26aa
movq %r14, %rax
testq %r15, %r15
je 0x269b
movq %r14, %rdi
leaq 0xaaf(%rip), %rsi       # 0x3145
callq 0x20e0
movq %rax, %rdi
movl %ebp, %esi
callq 0x21b0
incq %r15
jmp 0x266e
movq %r14, %rdi
leaq 0xa96(%rip), %rsi       # 0x314a
callq 0x20e0
movq %rax, %rdi
movaps 0x20(%rsp), %xmm0
callq 0x20a0
movq %rax, %rdi
leaq 0xa8f(%rip), %rsi       # 0x315f
callq 0x20e0
movq %rax, %rdi
movaps 0x10(%rsp), %xmm0
callq 0x20a0
movq %rax, %rdi
leaq 0xa8c(%rip), %rsi       # 0x3178
callq 0x20e0
movaps 0x10(%rsp), %xmm0
shufps $0x55, %xmm0, %xmm0     # xmm0 = xmm0[1,1,1,1]
movq %rax, %rdi
callq 0x20a0
movq %rax, %rdi
leaq 0xa83(%rip), %rsi       # 0x318f
callq 0x20e0
movq %rax, %rdi
callq 0x2090
movaps 0x20(%rsp), %xmm0
movss %xmm0, 0x280(%rsp)
movaps 0x10(%rsp), %xmm0
movlps %xmm0, 0x284(%rsp)
movups 0xbc(%rsp), %xmm0
leaq 0x28c(%rsp), %rax
movups %xmm0, 0x1c(%rax)
movaps 0xa0(%rsp), %xmm0
movaps 0xb0(%rsp), %xmm1
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
movq 0x8(%rsp), %rax
movq 0x18(%rax), %r8
movl 0x10(%rax), %r9d
movl %ebx, %edi
leaq 0x280(%rsp), %rsi
pushq $0x38
popq %rdx
xorl %ecx, %ecx
callq 0x2030
cmpl $-0x1, %eax
je 0x27ce
movq %r14, %rdi
leaq 0xa13(%rip), %rsi       # 0x31a2
callq 0x20e0
movq %rax, %rdi
callq 0x2090
leaq 0x30(%rsp), %rdi
callq 0x2070
leaq 0x50(%rsp), %rdi
callq 0x2070
leaq 0x100(%rsp), %rbp
movq %rbp, %rdi
callq 0x2080
jmp 0x247a
leaq 0x895(%rip), %rdi       # 0x3061
jmp 0x27d5
leaq 0x9be(%rip), %rdi       # 0x3193
callq 0x20c0
pushq $0x1
popq %rdi
callq 0x2110
jmp 0x280e
jmp 0x280e
jmp 0x27e8
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0x2070
leaq 0x50(%rsp), %rdi
callq 0x2070
leaq 0x100(%rsp), %rdi
callq 0x2080
jmp 0x2811
movq %rax, %rbx
leaq 0x70(%rsp), %rdi
callq 0x2070
movq %rbx, %rdi
callq 0x21c0