// File: /workspace/github_cpp_makefile_star2_O1/BruceHu1005[P]np-assignment1/servermain.cpp
// Function: main
int main(int argc, char *argv[]){
  
  /* Do more magic */
  int listen_fd;//to create socket
	int conn_fd;//to accept connection
	struct sockaddr_in serv_addr;//server receive on this address
	struct sockaddr_in client_addr;//server sends to client on this address
	struct sockaddr_storage their_addr;
	int recv_num;
	int send_num;
	char send_buf[BUFF_LEN] = "TEXT TCP 1.0, Enter OK to start!";
	char recv_buf[BUFF_LEN];
	socklen_t clientAddressLength;

  listen_fd=socket(AF_INET,SOCK_STREAM,0); 	 //create socket
	memset(&serv_addr,0,sizeof(serv_addr)); //initialize the socket addresses
	serv_addr.sin_family=AF_INET;
	serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);
	serv_addr.sin_port=htons(PORT);

  bind(listen_fd,(struct sockaddr *)&serv_addr, sizeof(serv_addr));
	listen(listen_fd,1);

  while(1) {
		printf("server wait:\n");
		clientAddressLength=sizeof(client_addr);
		conn_fd=accept(listen_fd,(struct sockaddr*)&client_addr, &clientAddressLength);
   
    //rceive from client
		send_num = send(conn_fd, send_buf, strlen(send_buf), 0);
		if (send_num < 0)
		{
			perror("send error:");
			exit(1);
		}
		recv_num = recv(conn_fd, recv_buf, sizeof(recv_buf), 0);
		if (recv_buf[0] == 'O'&&recv_buf[1] == 'K') {
			recv_buf[recv_num] = '\0';
			printf("server receive %d bytes: %s\n", recv_num, recv_buf);
			initCalcLib();
			char *ptr;
			ptr = randomType(); // Get a random arithemtic operator. 

			double f1, f2, fresult;
			int i1, i2, iresult;

			/* Act differently depending on what operator you got, judge type by first char in string. If 'f' then a float */

			if (ptr[0] == 'f') {
				printf("Float\t");
				f1 = randomFloat();
				f2 = randomFloat();

				/* At this point, ptr holds operator, f1 and f2 the operands. Now we work to determine the reference result. */

				if (strcmp(ptr, "fadd") == 0) {
					fresult = f1 + f2;
				}
				else if (strcmp(ptr, "fsub") == 0) {
					fresult = f1 - f2;
				}
				else if (strcmp(ptr, "fmul") == 0) {
					fresult = f1 * f2;
				}
				else if (strcmp(ptr, "fdiv") == 0) {
					fresult = f1 / f2;
				}
				printf("%s %8.8g %8.8g = %8.8g\n", ptr, f1, f2, fresult);
				char str[100];
				sprintf(str, "%s %8.8g %8.8g", ptr, f1, f2);
				send_num = send(conn_fd, str, strlen(str), 0);
				if (send_num < 0)
				{
					perror("sendto error:");
					exit(1);
				}
				recv_num = recv(conn_fd, recv_buf, sizeof(recv_buf), 0);
				if (recv_num < 0)
				{
					perror("recvfrom error:");
					exit(1);
				}
				recv_buf[recv_num] = '\0';
				printf("server receive %d bytes: %s\n", recv_num, recv_buf);
				
				char grade[20];
				if (fabs(stod(recv_buf)-fresult)<0.0001) {

					sprintf(grade, "%s", "OK");

				}
				else
				{
					sprintf(grade, "%s%8.8g", "ERROR, Right answer is ", fresult);
				}
				send_num = send(conn_fd, grade, strlen(grade), 0);
			}
			else {
				printf("Int\t");
				i1 = randomInt();
				i2 = randomInt();

				if (strcmp(ptr, "add") == 0) {
					iresult = i1 + i2;
				}
				else if (strcmp(ptr, "sub") == 0) {
					iresult = i1 - i2;
				}
				else if (strcmp(ptr, "mul") == 0) {
					iresult = i1 * i2;
				}
				else if (strcmp(ptr, "div") == 0) {
					iresult = i1 / i2;
				}

				printf("%s %d %d = %d \n", ptr, i1, i2, iresult);
				char str[100];
				sprintf(str, "%s %d %d", ptr, i1, i2);
				send_num = send(conn_fd, str, strlen(str), 0);
				if (send_num < 0)
				{
					perror("sendto error:");
					exit(1);
				}
				
				recv_num = recv(conn_fd, recv_buf, sizeof(recv_buf), 0);
				recv_buf[recv_num] = '\0';
				printf("server receive %d bytes: %s\n", recv_num, recv_buf);
				
				char grade[20];
				if (abs((stod(recv_buf)) - iresult) < 0.0001) {

					sprintf(grade, "%s", "OK");

				}
				else
				{
					sprintf(grade, "%s%d", "ERROR, Right answer is ", iresult);
				}
				send_num = send(conn_fd, grade, strlen(grade), 0);
				close(conn_fd);
			}

		}
		else {
			char buf[20]="disconnected";
			printf("Client refused connection\n");
			send_num = send(conn_fd, buf, strlen(buf), 0);
			close(conn_fd);
		}

	}
	close(listen_fd);
	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x508, %rsp            # imm = 0x508
leaq 0xd6f(%rip), %rsi       # 0x2160
leaq -0x530(%rbp), %r14
movl $0x200, %edx            # imm = 0x200
movq %r14, %rdi
callq 0x1100
movl $0x2, %edi
movl $0x1, %esi
xorl %edx, %edx
callq 0x1070
movl %eax, %ebx
xorps %xmm0, %xmm0
leaq -0xc0(%rbp), %rsi
movaps %xmm0, (%rsi)
movq $0x401f0002, (%rsi)     # imm = 0x401F0002
movl %eax, %edi
movl $0x10, %edx
callq 0x1050
movl %ebx, -0x74(%rbp)
movl %ebx, %edi
movl $0x1, %esi
callq 0x1160
leaq 0xce0(%rip), %rbx       # 0x212e
leaq -0xb0(%rbp), %r15
movq %rbx, %rdi
callq 0x11b0
movl $0x10, -0x78(%rbp)
movl -0x74(%rbp), %edi
movq %r15, %rsi
leaq -0x78(%rbp), %rdx
callq 0x1090
movl %eax, %r13d
movq %r14, %rdi
callq 0x10b0
movl %r13d, %edi
movq %r14, %rsi
movq %rax, %rdx
xorl %ecx, %ecx
callq 0x10c0
testl %eax, %eax
js 0x1a79
movl $0x200, %edx            # imm = 0x200
movl %r13d, %edi
leaq -0x330(%rbp), %rsi
xorl %ecx, %ecx
callq 0x10a0
cmpb $0x4f, -0x330(%rbp)
jne 0x14be
cmpb $0x4b, -0x32f(%rbp)
je 0x1510
movapd 0xe9a(%rip), %xmm0      # 0x2360
movapd %xmm0, -0x130(%rbp)
movl $0x0, -0x120(%rbp)
leaq 0xc5c(%rip), %rdi       # 0x213b
callq 0x11b0
leaq -0x130(%rbp), %r12
movq %r12, %rdi
callq 0x10b0
movl %r13d, %edi
movq %r12, %rsi
movq %rax, %rdx
xorl %ecx, %ecx
callq 0x10c0
movl %r13d, %edi
callq 0x11e0
jmp 0x1455
movslq %eax, %rsi
movb $0x0, -0x330(%rbp,%rsi)
leaq 0xb2e(%rip), %rdi       # 0x2050
leaq -0x330(%rbp), %rbx
movq %rbx, %rdx
xorl %eax, %eax
callq 0x1040
leaq 0x2c2e(%rip), %rdi      # 0x4168
callq 0x1130
movl %eax, %edi
callq 0x1140
callq 0x1080
leal 0x7(%rax), %ecx
testl %eax, %eax
cmovnsl %eax, %ecx
andl $-0x8, %ecx
subl %ecx, %eax
cltq
leaq 0x2baf(%rip), %rcx      # 0x4110
movq (%rcx,%rax,8), %r12
cmpb $0x66, (%r12)
je 0x17de
leaq 0xb65(%rip), %rdi       # 0x20dc
xorl %eax, %eax
callq 0x1040
callq 0x1080
movslq %eax, %r15
imulq $0x51eb851f, %r15, %rax # imm = 0x51EB851F
movq %rax, %rcx
shrq $0x3f, %rcx
sarq $0x25, %rax
addl %ecx, %eax
imull $0x64, %eax, %eax
subl %eax, %r15d
callq 0x1080
movslq %eax, %rbx
imulq $0x51eb851f, %rbx, %rax # imm = 0x51EB851F
movq %rax, %rcx
shrq $0x3f, %rcx
sarq $0x25, %rax
addl %ecx, %eax
imull $0x64, %eax, %eax
subl %eax, %ebx
movq %r12, %rdi
leaq 0xa6b(%rip), %rsi       # 0x2036
callq 0x1180
testl %eax, %eax
movl -0x2c(%rbp), %eax
movq %r12, -0xa0(%rbp)
je 0x1629
movl %eax, -0x2c(%rbp)
movq %r12, %rdi
leaq 0xa46(%rip), %rsi       # 0x2031
callq 0x1180
testl %eax, %eax
je 0x162f
movq %r12, %rdi
leaq 0xa42(%rip), %rsi       # 0x2040
callq 0x1180
testl %eax, %eax
je 0x1637
movq %r12, %rdi
leaq 0xa2a(%rip), %rsi       # 0x203b
callq 0x1180
testl %eax, %eax
movl -0x2c(%rbp), %r8d
jne 0x163e
movl %r15d, %eax
cltd
idivl %ebx
movl %eax, %r8d
jmp 0x163e
leal (%rbx,%r15), %r8d
jmp 0x163e
movl %r15d, %r8d
subl %ebx, %r8d
jmp 0x163e
movl %ebx, %r8d
imull %r15d, %r8d
leaq 0xa9c(%rip), %rdi       # 0x20e1
movq -0xa0(%rbp), %r12
movq %r12, %rsi
movl %r15d, %edx
movl %ebx, %ecx
movl %r8d, -0x2c(%rbp)
xorl %eax, %eax
callq 0x1040
leaq -0x130(%rbp), %rdi
leaq 0xa84(%rip), %rsi       # 0x20f1
movq %r12, %rdx
movl %r15d, %ecx
movl %ebx, %r8d
xorl %eax, %eax
callq 0x1060
leaq -0x130(%rbp), %rbx
movq %rbx, %rdi
callq 0x10b0
movl %r13d, %edi
movq %rbx, %rsi
movq %rax, %rdx
xorl %ecx, %ecx
callq 0x10c0
testl %eax, %eax
js 0x1a8f
movl $0x200, %edx            # imm = 0x200
movl %r13d, %edi
leaq -0x330(%rbp), %rbx
movq %rbx, %rsi
xorl %ecx, %ecx
callq 0x10a0
movslq %eax, %rsi
movb $0x0, -0x330(%rbp,%rsi)
leaq 0x981(%rip), %rdi       # 0x2050
movq %rbx, %rdx
xorl %eax, %eax
callq 0x1040
leaq -0x58(%rbp), %rax
movq %rax, -0x68(%rbp)
movq %rbx, %rdi
callq 0x10b0
leaq (%rax,%rbp), %rdx
addq $-0x330, %rdx           # imm = 0xFCD0
leaq -0x68(%rbp), %rdi
movq %rbx, %rsi
callq 0x1b08
movq -0x68(%rbp), %rbx
callq 0x1030
movq %rax, %r15
movl (%rax), %r12d
movl $0x0, (%rax)
movq %rbx, %rdi
leaq -0x70(%rbp), %rsi
callq 0x10f0
cmpq %rbx, -0x70(%rbp)
je 0x1a98
movapd %xmm0, %xmm1
movl (%r15), %eax
testl %eax, %eax
je 0x1740
cmpl $0x22, %eax
jne 0x1743
jmp 0x1aa4
movl %r12d, (%r15)
movq -0x68(%rbp), %rdi
leaq -0x58(%rbp), %rax
cmpq %rax, %rdi
je 0x176c
movq -0x58(%rbp), %rsi
incq %rsi
movapd %xmm1, -0xa0(%rbp)
callq 0x1150
movapd -0xa0(%rbp), %xmm1
movl -0x2c(%rbp), %ecx
xorps %xmm0, %xmm0
cvtsi2sd %ecx, %xmm0
subsd %xmm0, %xmm1
andpd 0x89e(%rip), %xmm1      # 0x2020
movsd 0x886(%rip), %xmm0      # 0x2010
ucomisd %xmm1, %xmm0
leaq 0x999(%rip), %rbx       # 0x212e
leaq -0xb0(%rbp), %r15
jbe 0x17ba
movb $0x0, -0x8e(%rbp)
movw $0x4b4f, -0x90(%rbp)    # imm = 0x4B4F
leaq -0x90(%rbp), %r12
jmp 0x14eb
leaq -0x90(%rbp), %r12
movq %r12, %rdi
leaq 0x92f(%rip), %rsi       # 0x20fa
leaq 0x8f2(%rip), %rdx       # 0x20c4
xorl %eax, %eax
callq 0x1060
jmp 0x14eb
leaq 0x888(%rip), %rdi       # 0x206d
xorl %eax, %eax
callq 0x1040
callq 0x1080
cvtsi2sd %eax, %xmm1
movsd 0x80b(%rip), %xmm0      # 0x2008
divsd %xmm0, %xmm1
movsd %xmm1, -0x40(%rbp)
callq 0x1080
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
divsd 0x7ee(%rip), %xmm0      # 0x2008
movsd %xmm0, -0x38(%rbp)
movq %r12, %rdi
leaq 0x80c(%rip), %rsi       # 0x2035
callq 0x1180
testl %eax, %eax
je 0x1884
movq %r12, %rdi
leaq 0x7f4(%rip), %rsi       # 0x2030
callq 0x1180
testl %eax, %eax
je 0x1898
movq %r12, %rdi
leaq 0x7f0(%rip), %rsi       # 0x203f
callq 0x1180
testl %eax, %eax
je 0x18ac
movq %r12, %rdi
leaq 0x7d8(%rip), %rsi       # 0x203a
callq 0x1180
testl %eax, %eax
movsd -0x48(%rbp), %xmm2
movsd -0x40(%rbp), %xmm0
movsd -0x38(%rbp), %xmm1
jne 0x18be
movapd %xmm0, %xmm2
divsd %xmm1, %xmm2
jmp 0x18be
movsd -0x40(%rbp), %xmm0
movapd %xmm0, %xmm2
movsd -0x38(%rbp), %xmm1
addsd %xmm1, %xmm2
jmp 0x18be
movsd -0x40(%rbp), %xmm0
movapd %xmm0, %xmm2
movsd -0x38(%rbp), %xmm1
subsd %xmm1, %xmm2
jmp 0x18be
movsd -0x40(%rbp), %xmm0
movapd %xmm0, %xmm2
movsd -0x38(%rbp), %xmm1
mulsd %xmm1, %xmm2
leaq 0x7af(%rip), %rdi       # 0x2074
movq %r12, %rsi
movsd %xmm2, -0x48(%rbp)
movb $0x3, %al
callq 0x1040
leaq -0x130(%rbp), %r15
movq %r15, %rdi
leaq 0x7a7(%rip), %rsi       # 0x208c
movq %r12, %rdx
movsd -0x40(%rbp), %xmm0
movsd -0x38(%rbp), %xmm1
movb $0x2, %al
callq 0x1060
movq %r15, %rdi
callq 0x10b0
movl %r13d, %edi
movq %r15, %rsi
movq %rax, %rdx
xorl %ecx, %ecx
callq 0x10c0
testl %eax, %eax
js 0x1a8f
movl $0x200, %edx            # imm = 0x200
movl %r13d, %edi
movq %rbx, %rsi
xorl %ecx, %ecx
callq 0x10a0
testl %eax, %eax
js 0x1ab0
movl %eax, %ecx
andl $0x7fffffff, %ecx       # imm = 0x7FFFFFFF
movb $0x0, -0x330(%rbp,%rcx)
leaq 0x706(%rip), %rdi       # 0x2050
movl %eax, %esi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x1040
leaq -0x58(%rbp), %rax
movq %rax, -0x68(%rbp)
movq %rbx, %rdi
callq 0x10b0
leaq (%rax,%rbp), %rdx
addq $-0x330, %rdx           # imm = 0xFCD0
leaq -0x68(%rbp), %rdi
movq %rbx, %rsi
callq 0x1b08
movq -0x68(%rbp), %rbx
callq 0x1030
movq %rax, %r15
movl (%rax), %r12d
movl $0x0, (%rax)
movq %rbx, %rdi
leaq -0x70(%rbp), %rsi
callq 0x10f0
cmpq %rbx, -0x70(%rbp)
je 0x1ab9
movapd %xmm0, %xmm2
movl (%r15), %eax
testl %eax, %eax
je 0x19c2
cmpl $0x22, %eax
movsd -0x48(%rbp), %xmm1
jne 0x19ca
jmp 0x1ac5
movl %r12d, (%r15)
movsd -0x48(%rbp), %xmm1
movq -0x68(%rbp), %rdi
leaq -0x58(%rbp), %rax
cmpq %rax, %rdi
je 0x19f8
movq -0x58(%rbp), %rsi
incq %rsi
movapd %xmm2, -0xa0(%rbp)
callq 0x1150
movapd -0xa0(%rbp), %xmm2
movsd -0x48(%rbp), %xmm1
subsd %xmm1, %xmm2
andpd 0x61c(%rip), %xmm2      # 0x2020
movsd 0x604(%rip), %xmm0      # 0x2010
ucomisd %xmm2, %xmm0
leaq 0x717(%rip), %rbx       # 0x212e
leaq -0xb0(%rbp), %r15
jbe 0x1a39
movb $0x0, -0x8e(%rbp)
movw $0x4b4f, -0x90(%rbp)    # imm = 0x4B4F
leaq -0x90(%rbp), %r12
jmp 0x1a5c
leaq -0x90(%rbp), %r12
movq %r12, %rdi
leaq 0x672(%rip), %rsi       # 0x20bc
leaq 0x673(%rip), %rdx       # 0x20c4
movapd %xmm1, %xmm0
movb $0x1, %al
callq 0x1060
movq %r12, %rdi
callq 0x10b0
movl %r13d, %edi
movq %r12, %rsi
movq %rax, %rdx
xorl %ecx, %ecx
callq 0x10c0
jmp 0x1455
leaq 0x5c4(%rip), %rdi       # 0x2044
callq 0x1110
movl $0x1, %edi
callq 0x1170
leaq 0x605(%rip), %rdi       # 0x209b
jmp 0x1a80
leaq 0x660(%rip), %rdi       # 0x20ff
callq 0x10d0
leaq 0x654(%rip), %rdi       # 0x20ff
callq 0x1190
leaq 0x5f2(%rip), %rdi       # 0x20a9
jmp 0x1a80
leaq 0x63f(%rip), %rdi       # 0x20ff
callq 0x10d0
leaq 0x633(%rip), %rdi       # 0x20ff
callq 0x1190
jmp 0x1ad5
jmp 0x1ada
movq %rax, %rbx
jmp 0x1aff
movq %rax, %rbx
cmpl $0x0, (%r15)
jne 0x1ae6
movl %r12d, (%r15)
movq -0x68(%rbp), %rdi
leaq -0x58(%rbp), %rax
cmpq %rax, %rdi
je 0x1aff
movq -0x58(%rbp), %rsi
incq %rsi
callq 0x1150
movq %rbx, %rdi
callq 0x11c0
nop