#include <stdio.h>
#include <stdlib.h>
#include "header.h"

#ifdef WIN32
  #include <winsock.h>
  #include <windows.h>
#else
  #include <sys/types.h>
  #include <sys/socket.h>
  #include <netinet/in.h>
  #include <arpa/inet.h>
  #include <netdb.h>
  #define  closesocket close
#endif

#ifndef SOCKET
  #define SOCKET 		int
#endif

#ifndef SOCKET_ERROR
  #define SOCKET_ERROR  -1
#endif


#define BUFSIZE 1024*1024

//int reqMsg[BUFSIZE];
struct requisicao reqMsg;
struct resposta x,repMsg;

int main(int argc, char *argv[])
{
   //apenas windows
   #ifdef WIN32
   WSADATA wsda;	
   #endif
		
   struct hostent *host;	// Estrutura para armazenar a estrutura de nomes de host

   int ret, i, tamAddr, nPorta, tamBuf;
   char addrHost[64];
   struct requisicao reqMsg;
   struct resposta repMsg;


   SOCKET s;		        // socket para conectar com servior
   struct sockaddr_in addr;	// Endereço do Servidor

   // Conferindo argumentos
   if(argc != 3 ||
      (argc==2 && strcmp((char *) &argv[1][0], "/?")==0))
   {
      printf("Cliente [maquina] nPorta\n");
      printf("   maquina: endereco IP do servidor\n");
      printf("   nPorta:  numero da porta do servidor\n");
      exit(1);
   }

   // Pego o IP passado na linha de comando
   strcpy(addrHost, (char *) &argv[1][0]);

   // pego o numro da porta
   nPorta = atoi((char *) &argv[2][0]);

   if(nPorta<0 || nPorta>65535)
   {
      printf("Numero de Porta invalido (%s)\n", argv[2]);
      exit(1);
   }

   // somente para windows - carrega a biblioteca
   #ifdef WIN32
   WSAStartup(MAKEWORD(1,1), &wsda);
   #endif

   // Cria o Socket para conectar
   printf("Criando Socket...\n");
   s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);

   // Erro?
   if(s == SOCKET_ERROR)
   {
      printf("Nao consegui criar o socket\n");
      exit(1);
   }

   // Preenche as informacoes da maquina destino
   addr.sin_family = AF_INET;
   addr.sin_port = htons(nPorta);
   addr.sin_addr.s_addr = inet_addr(addrHost);

   if(addr.sin_addr.s_addr == INADDR_NONE) 	// O endereco nao eh IP, eh uma string, resolva o nome
   {
      host = NULL;
      printf("Encontrando IP do Host %s\n",addrHost);
      host = gethostbyname(addrHost);	    // Pego o Endereço do host destino

      if(host == NULL)
      {
         printf("Erro! Host Desconhecido: %s\n", addrHost);
         exit(1);
      }
      memcpy(&addr.sin_addr, host->h_addr_list[0], host->h_length);
   }

   // Connect to the server
   printf("Conectando em %s:%d...\n",addrHost, nPorta);
   
   ret = connect(s, (struct sockaddr *) &addr, sizeof(addr));

   if(ret == SOCKET_ERROR)
   {
      printf("Erro no Conect - servidor nao esta no Ar\n");
      exit(1);
   }
   // Ready to send data

 
   
   printf("Digite a expressao:");
   scanf("%d%c%d",&reqMsg.n1, &reqMsg.op, &reqMsg.n2);
   ret = send(s,(void*)&reqMsg,sizeof(struct requisicao),0);
   
   ret = recv(s,(void*)&repMsg,sizeof(struct resposta),0);
   
  
   if (repMsg.erro == OK)
   {
      printf("Sucesso - Resultado = %d\n",x.resultado);
   }
   else if (repMsg.erro == DIV_ZERO)
   {
        printf("Erro - Divisao por zero\n");
   }
   else
        printf("Operacao nao implementada ainda...\n");
   

   closesocket(s);

   #ifdef WIN32
   WSACleanup();
   #endif

   return 0;
}
