#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sys/socket.h>
#include <netdb.h>

#define ERR(a) fprintf(stderr, "Error: %s\n", a)

int main()
{
   // client variables
   int client;
   struct addrinfo hints, *server_info;

   // calculation variables
   uint32_t n, fib_n;

   // Get the address & some socket information
   memset((void *) &hints, 0, sizeof(hints));      // zero out the structure
   hints.ai_family = AF_INET;          // use IPv4
   hints.ai_socktype = SOCK_STREAM;    // give me a "stream socket" rather than a "datagram socket"

   getaddrinfo("127.0.0.1", "4000", &hints, &server_info);     // Get me the information for the localhost at port 4000

   // Get an actual network socket
   client = socket(server_info->ai_family, server_info->ai_socktype, server_info->ai_protocol);
   if (client < 0)
   {
      ERR("could not get a socket!");
      return -1;
   }

   // Connect the socket to the desired address where the server is listening
   if (connect(client, server_info->ai_addr, server_info->ai_addrlen) < 0)
   {
      ERR("could not connect to the server!");
      return -1;
   }

   printf("Connected to the server!\n");

   do
   {
      printf("Please enter a number: ");
      scanf("%d", &n);

      // NOTE: usually the data sent must be in "network order" and should be
      // changed from "host order". This will be explained in the next lecture,
      // and is skipped for now

      send(client, (void *) &n, sizeof(uint32_t), 0); // send a message to the server
      // NOTE: as before, you should check the return of send to see how many
      // bytes were sent and if there were any errors. But we will skip that now

      recv(client, (void *) &fib_n, sizeof(uint32_t), 0);      // receive a message from the server
      // NOTE: you should check the reutrn result of recv to see how many bytes
      // were received or if there was an error. But we will skip that for now

      printf("The server says that fib(%d) = %d\n", n, fib_n);
   } while(n > 0);

   // We are done! Close the client network socket
   close(client);

   return 0;
}