#include <stdio.h>
#include <time.h>
#include "Syslog.h"
#include "System.h"
#include "AcousticMsgHandler.h"
#include "Task.h"

#define MaxMessageBytes 50

class ModemTest : public Task {

public:

  ModemTest(StringMsgHandler *handler, const char *logfileName);
  ~ModemTest();

  void run();

protected:

  void processRecord(char *record, int nRecordBytes);

  StringMessage *_inputMessage;
  StringMessages _outputMessages;
  StringMsgHandler *_handler;
  char *_logFileName;
};



ModemTest::ModemTest(StringMsgHandler *handler, const char *logfileName)
  : Task("modemTest")
{
  _handler = handler;

  _inputMessage = new StringMessage(MaxMessageBytes, AcousticTokenDelimiter);

  _logFileName = strdup(logfileName);
}


ModemTest::~ModemTest()
{
  delete _inputMessage;
  free((void *)_logFileName);
}


void ModemTest::run()
{
  char buf[256];
  int sequenceNo = 1;

  while (True) {

    printf("Enter command: ");
    gets(buf);

    if (sequenceNo > 9)
      sequenceNo = 1;

    // Set sequence number
    sprintf(&buf[1], "%d", sequenceNo++);

    // Set time
    sprintf(&buf[2], "%d", time(0));

    processRecord(buf, strlen(buf));
  }
}


void ModemTest::processRecord(char *record, int nRecordBytes)
{
  Boolean debug = True;
  dprintf("ModemTest::processRecord(): %s", record);
  Boolean error = False;

  if (!strncmp(record, "q", 1)) {
    // Quit
    exit(0);
  }


  _inputMessage->setBuffer((char *)record);

  try {
    _handler->process(_inputMessage, &_outputMessages);
  }
  catch (Exception e) {
    fprintf(stderr, "Caught exception: %s\n", e.msg);
    fprintf(stderr, 
	    "Valid commands:\n"
	    "%d (request navigation packet)\n"
	    "%d (request mission status)\n"
	    "%d (request abort)\n"
	    "MSG (default MSG request)\n"
	    "q (quit)\n",
	    AcousticMessage::Navigation,
	    AcousticMessage::MissionState,
	    AcousticMessage::ChangeState);

    return;
  }

  FILE *logFile;
  if ((logFile = fopen(_logFileName, "a+w")) == 0) {
    fprintf(stderr, "Couldn't open log file \"%s\"\n", _logFileName);
    return;
  }

  for (int i = 0; i < _outputMessages.size(); i++) {

    StringMessage *telemetry;
    _outputMessages.get(i, &telemetry);

    // Pad out-going message with blanks
    telemetry->pad(' ');

    fprintf(stderr, "%s\n", telemetry->buffer());

    // Write reply to logfile
    fprintf(logFile, "%s\n", telemetry->buffer());
  }

  fclose(logFile);
}


int main(int argc, char **argv)
{
  if (argc != 2) {
    fprintf(stderr, "usage: %s logfile\n", argv[0]);
    return 1;
  }

  const char *logfile = argv[1];

  // Set task priority
  if (System::setTaskPriority(NonCriticalDriverPriority) == -1)
    return 1;

  ModemTest *modem = 0;
  AcousticMsgHandler *handler = 0;

  try {
    handler = new AcousticMsgHandler(MaxMessageBytes);
    modem = new ModemTest(handler, logfile);
    modem->run();
  }
  catch (Exception e) {
    Syslog::write("%s - caught Exception: %s\n", argv[0], e.msg);
  }
  catch (...) {
    Syslog::write("%s - caught unknown exception\n", argv[0]);
  }

  delete modem;
  delete handler;

  return 0;
}
