#include "TFTPClient.h"

int main( int argc, char** argv)
{
     /*argc = 4;
    argv[1] = "222.205.41.160";
    argv[2] = "GET";
    argv[3] = "bb.txt";*/

     /*argc = 5;
    argv[1] = "-i";
    argv[2] = "222.205.41.160";
    argv[3] = "GET";
    argv[4] = "Cantor.zip";*/

     //freopen("out.txt", "w", stdout);
     if(argc < 4)
    {
  help();
  exit(1);
    }
    parseCmd(argc, argv); //Parse the command line commands

    SOCKET sock = initWinsock();
    sockaddr_in servAddr;
    servAddr.sin_family = AF_INET;
    servAddr.sin_port = htons(SERV_PORT);
    servAddr.sin_addr.s_addr = cmd.hostaddr;
     char buf[MAX_BUF];
     int startTime = int(GetTickCount());
    fileSize = 0;

     if(cmd.put == 1)
    {
   //Begin initialize the WRQ packet
  WRQNode node;
  memset(&node, 0, sizeof(node));
  strcpy(node.fileName, cmd.fileName.c_str());
  node.opCode = 2;
   if(cmd.binFlag == 0)
      strcpy(node.mode, "netascii");
   else
   if(cmd.binFlag == 1)
      strcpy(node.mode, "octet");
   //End initialize the WRQ packet

   //Begin sending the WRQ packet
  sockaddr_in addr;
   int len = sizeof(addr);
  ACKNode ackNode;
   do
  {
       int size = makeWRQ(node, buf, sizeof(buf));
       if(sendto(sock, buf, size, 0, (sockaddr*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)
      {
    cerr << "Error at sendto(): " << WSAGetLastError() << endl;
    WSACleanup();
     return 1;
      }
      memset(buf, 0, sizeof(buf));
       int ret = recvfrom(sock, buf, sizeof(buf), 0, (sockaddr*)&addr, &len);
       if(ret == SOCKET_ERROR)
      {
    cerr << "Error at recvfrom(): " << WSAGetLastError() << endl;
    WSACleanup();
     return 1;
      }
       if (getOp(buf) == ERR)
      {
    ERRNode errNode;
    parseERR(buf, errNode);
    cout << "Error: " << errNode.errMsg << endl;
     return 1;
      }
       else
    parseACK(buf, ackNode);
  } while(ackNode.opCode != 4 || ackNode.blockNumber != 0);
   //End sending the WRQ packet and received the ACK packet successfully
  
   //Begin sending the file
   if(sendFile(sock, (sockaddr*)&addr))
  {
       int endTime = int(GetTickCount());
      printInfo(cmd.fileName.c_str(), endTime - startTime, fileSize);
  }
   //End sending the file and successfully received last ACK packet

   //Close the connection
  closesocket(sock);
  WSACleanup();
   return 0;
    }
     else
     if(cmd.get == 1)
    {
   //Begin initialize the RRQNode
  RRQNode rrqNode;
  memset(&rrqNode, 0, sizeof(rrqNode));
  rrqNode.opCode = 1;
  strcpy(rrqNode.fileName, cmd.fileName.c_str());
   if(cmd.binFlag == 0)
      strcpy(rrqNode.mode, "netascii");
   else
   if(cmd.binFlag == 1)
      strcpy(rrqNode.mode, "octet");
   //End initialize the RRQNode

   //Begin send the RRQNode
   int ret = makeRRQ(rrqNode, buf, sizeof(buf));
   if(sendto(sock, buf, ret, 0, (sockaddr*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)
  {
      cout << "Error at sendto(): " << WSAGetLastError() << endl;
      WSACleanup();
       return 1;
  }
   //End send the RRQNode

   //Begin receive the file
   if(recvFile(sock))
  {
       int endTime = int(GetTickCount());
      printInfo(cmd.fileName.c_str(), endTime - startTime, fileSize);
  }
   //End receive the file

   //Close the connection
  closesocket(sock);
  WSACleanup();
   return 0;
    }
     return 0;
}