/*********************************************************************/
/* TCP Server of the Mastermind game                                 */
/*                                                                   */
/*                                                                   */
/* Prepared by Eddie Aronovich                                       */
/*********************************************************************/


    #include <stdio.h> 
    #include <stdlib.h> 
    #include <errno.h> 
    #include <string.h> 
    #include <sys/types.h> 
    #include <netinet/in.h> 
    #include <sys/socket.h> 
    #include <sys/wait.h> 
    #include <sys/time.h>
    #include <sys/unistd.h>

    #define MYPORT 9999   /* the port users will be connecting to */
    #define MAXBUFLEN 100
    #define BACKLOG 10     /* how many pending connections queue will hold */

    main()
    {
        int 	sockfd, new_fd;		/* listen on sock_fd, new connection on new_fd 	*/
        struct 	sockaddr_in my_addr;	/* my address information 			*/
        struct 	sockaddr_in their_addr;	/* connector's address information 		*/
        int 	sin_size;
        int     i;
	int	numbytes;		/* number of bytes read / write to the socket	*/
        int     chosen_digit;		/* Each digit that the user chosed		*/
        char    chosen_number[5];	/* The number received from the user		*/
	char    buf[MAXBUFLEN]; 
 

	/*----------------------------------------*/
	/*Choosing the number to be guessed later */
	/*----------------------------------------*/
        chosen_number[0] = '\0';
       	for (i=0;i<4;i++){ /*Separating the numer into digits */
		chosen_digit=(int) (10.0*rand()/(RAND_MAX+1.0));
		if (index(chosen_number, chosen_digit+48) == 0 ){
                      		chosen_number[i] = chosen_digit + 48; /*Adding 48 to convert between ASCII char and digit */
                      		chosen_number[i+1]='\0';
		}
		else
			i--;
       	}
			printf("The chosen number by the server is : %s \n", chosen_number);
        if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
            perror("socket");
            exit(1);
        }
	
	/*Some preparations are done in order to be able to bind the right port	*/
	
        my_addr.sin_family = AF_INET;         /* host byte order 	*/
        my_addr.sin_port = htons(MYPORT);     /* short, network byte order */
        my_addr.sin_addr.s_addr = INADDR_ANY; /* auto-fill with my IP */
        bzero(&(my_addr.sin_zero), 8);        /* zero the rest of the struct */

        if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) \
                                                                      == -1) {
            perror("bind");
            exit(1);
        }

        if (listen(sockfd, BACKLOG) == -1) {
            perror("listen");
            exit(1);
        }

        while(1) {  /* main accept() loop */
            sin_size = sizeof(struct sockaddr_in);
            if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, \
                                                          &sin_size)) == -1) {
                perror("accept");
                continue;
            }
            printf("server: got connection from %s\n", \
                                               inet_ntoa(their_addr.sin_addr));
            if (!fork()) { /* this is the child process */
		
		if ((numbytes=recv(new_fd, buf, MAXBUFLEN, 0)) == -1) {/*Recieve infor from the server*/
			perror("recv");
            		exit(1);
        	}
		buf[numbytes] = '\0'; /*The info from the server has no \0 at the end of string         */
		printf("got packet from %s, that contains: '%s' which is %d bytes long \n ",inet_ntoa(their_addr.sin_addr),buf,numbytes);
		if (check_reply(chosen_number, buf, new_fd, their_addr) == -1) {
			perror("Check reply");
			exit(1);
		}



  		
		 
                close(new_fd);
                exit(0);
            }
            close(new_fd);  /* parent doesn't need this */

            while(waitpid(-1,NULL,WNOHANG) > 0); /* clean up child processes */
        }
    }

int check_reply(char chosen_number[],char buf[], int new_fd,  struct sockaddr_in their_addr){

        int     i;
        int     digits;         /*number of right digit only */
        int     exact;          /*number of right exact digits & location */
        int     find_place;
        int     digit;
        int     numbytes;
        char    guess_number[5];
        char    user_id[5];
        char    user_number[5];
        char    one_char_string[2];
        char    reply[5]="nDnE";



        /*Striping the number that the user tried to guess */
        for (i=0;i<4;i++){
                guess_number[i] = buf[i]; /*copying the user guess to a different variable */
        }
        guess_number[4]='\0';

        /*Striping the user ID */
        for (i=0;i<4;i++){
                user_id[i] = buf[i+5]; /*copying the user ID to a different variable */
        }
        user_id[4]='\0';

        /*Striping the number that the user tried to guess */
        for (i=0;i<4;i++){
                user_number[i] = buf[i+10]; /*copying the user guess to a different variable */
        }
        user_number[4]='\0';

        /*printf("In the check routine, chosen_number = %s, buf = %s, guess_number=%s, user_id=%s, user_number=%s \n",chosen_number, buf,guess_number, user_id, user_number); */
        
	digits=exact=0;
        one_char_string[1] = '\0';
	        for (i=0;i<4;i++){

                one_char_string[0] = user_number[i];
                digit = user_number[i];
                printf("the tested char is: = %s \t",one_char_string);

                /*find_place = strncmp(chosen_number, one_char_string, 4);*/
                /*find_place = strcmp(chosen_number, one_char_string); */
                (char) find_place = index(chosen_number, digit);
                /*printf("found_place = %c \n", find_place);            */
                if (find_place == 0 ){
                        printf("this digit was not found \n");
                        }

                else{
                        printf("this digit (digit at offset %d) was found. The finding corresponds ", i);
                        if (user_number[i] == chosen_number[i]){
                                printf("value & position \n");
                                exact++;
                        }
                        else {
                                printf("value only \n");
                                digits++;
                        }
                }
        }
        printf("digits=%d, exact = %d \n",digits, exact);
        reply[0] = digits + 48;
        reply[2] = exact + 48;
        reply[4] = '\0';


        if ((numbytes=send(new_fd, reply, strlen(reply), 0)) == -1) {
                perror("send");
                exit(1);
        }
        else
                printf("sent %d bytes to %s: %s\n",numbytes,inet_ntoa(their_addr.sin_addr),reply);



        return 0;
}
 
  
