#include "FTPClient.h"

FTPClient::FTPClient(WiFiClient client, uint8_t id, uint16_t clientCommandDataBufferSize) : TCPClient(client, id, clientCommandDataBufferSize),
_ftpCommand({'\0'}),
_cmdParameters(NULL),
_loggedIn(false),
_username(NULL),
_currentDirectory(NULL),
_currentFile(NULL),
_fileSentBytes(0),
_fileRecvBytes(0),
_waitingForDataConnection(false),
_fileIsBeeingReceived(false),
_actionTimeout(0),
_dataClientConnected(false),
_ftpClientState(FTPServer<FTPClient>::FTPClientState::INIT),
_binaryFlag(FTPServer<FTPClient>::BinaryFlag::OFF),
_dataTransferPending(FTPServer<FTPClient>::FTPClientDataTransfer::NONE)
{
  
}

FTPClient::~FTPClient()
{
	delete _cmdParameters;
  free(_username);
  free(_currentDirectory);
  free(_currentFile);
  _dataClient.stop();
}

void FTPClient::setDataClient(WiFiClient dataClient)
{
  _dataClientConnected = true;
  _dataClient = dataClient;
}

boolean FTPClient::parseCommandAndParameters()
{
  //We remove the cr lf at the end
  char *cr = strchr((char *)_data,'\r');
  
  if(cr != NULL)
  {
    *cr = '\0';
    //Serial.println("got r");
  }
  else
  {
    cr = strchr((char *)_data,'\n');
    if(cr != NULL)
    {
      *cr = '\0';
      //Serial.println("got n");
    } 
  }
  
  //Serial.printf("Data : #%s#\n", (char *)_data);
  char *cmdDelimiter = strchr((char *)_data,' ');
  
  if(cmdDelimiter == NULL) //It means that we do not have any parameters
  {
    uint16_t dataSize = strlen((char *)_data);
    cmdDelimiter = (char *)_data + dataSize - 1;
    strncpy(_ftpCommand, (char *)_data, dataSize <= 4 ? dataSize : 4);
    _ftpCommand[dataSize <= 4 ? dataSize : 4] = '\0';
    //Serial.printf("Got no space : size %d\n", dataSize);
  }
  else //we do
  {
    uint16_t dataSize = cmdDelimiter - (char *)_data;
    
    strncpy(_ftpCommand, (char *)_data, dataSize <= 4 ? dataSize : 4);
    _ftpCommand[dataSize <= 4 ? dataSize : 4] = '\0'; // /!\ strncpy does not append the terminating string character
    //Serial.printf("Got a space : size %d\n", dataSize);
  }
  
  //We get the parameters : 
  DictionaryHelper::StringEntity params(cmdDelimiter+1); //+1 to skip the first space
  delete _cmdParameters;
  _cmdParameters = params.split(' ');
  //At the end, we flush the buffer:
  freeDataBuffer(_dataSize);

  return true;
}

void FTPClient::setUsername(const char *username)
{
  free(_username);_username = NULL;
  if(username != NULL)
  {
    _username = (char *) malloc((sizeof(char) * strlen(username)) + 1);
    strcpy(_username, username);
  }
}

void FTPClient::setCurrentDirectory(const char *dir)
{
  free(_currentDirectory);_currentDirectory = NULL;
  if(dir != NULL)
  {
    _currentDirectory = (char *) malloc((sizeof(char) * strlen(dir)) + 1);
    strcpy(_currentDirectory, dir);
  }
}

void FTPClient::setCurrentFile(const char *file)
{
  free(_currentFile);_currentFile = NULL;
  if(file != NULL)
  {
    _currentFile = (char *) malloc((sizeof(char) * strlen(file)) + 1);
    strcpy(_currentFile, file);
  }
}

void FTPClient::closeDataConnection()
{
  _dataClientConnected = false;
  _dataClient.stop();
}

void FTPClient::startTimeout()
{
  _actionTimeout = millis();
}
