#include <cstdio>
#include <cstdlib>
#include <cstdint>
#include <string>
#include <cstring>
#include <ctime>

#if defined(WIN32) || defined(__MINGW32__)
#include <windows.h>
#else
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <cerrno>
#include <dirent.h>

#ifdef __APPLE__
#include <IOKit/IOKitLib.h>
#include <IOKit/serial/IOSerialKeys.h>
#include <IOKit/usb/USBSpec.h>
#endif
#endif

template <int a, int b, int c, int d>
struct FourCCMake
{
  static const unsigned int value = (((((d << 8) | c) << 8) | b) << 8) | a;
};

bool Get32BlitInfo(uint32_t &uAck);

void usage()
{
  printf("Usage: 32blit <process> <comport> <binfile> <options>\n");
  printf("  <process> : Either _RST, SAVE or PROG\n");
  printf("  <comport> : Com port, eg COM1 or /dev/cu.usbmodem\n");
  printf("  <binfile> : Bin file path (optional, needed for SAVE and PROG)\n");
  printf("\nOptions:\n");
  printf("\t--reconnect: Re-open port after PROG to show debug output\n");
}

const char *getFileName(const char *pszPath)
{
  const char *pszFilename = strrchr(pszPath, '\\');
  if (pszFilename == nullptr)
    pszFilename = strrchr(pszPath, '/');

  if (pszFilename ==nullptr)
    pszFilename = pszPath;
  else
    pszFilename++;

  return pszFilename;
}




#ifdef WIN32
#ifndef __MINGW32__
typedef long ssize_t;
#endif
HANDLE hComm = INVALID_HANDLE_VALUE;
OVERLAPPED osRX = { 0 };
OVERLAPPED osTX = { 0 };
bool bWaitingOnRx = false;

void CloseCom()
{
  CloseHandle(osRX.hEvent);
  CloseHandle(osTX.hEvent);
  CloseHandle(hComm);
  hComm = INVALID_HANDLE_VALUE;
}

bool OpenComPort(const char *pszComPort, bool bTestConnection = false)
{
  bWaitingOnRx = false;

  if (hComm != INVALID_HANDLE_VALUE)
    CloseCom();

  osRX.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  osTX.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

  char pszFullPortName[32];
  snprintf(pszFullPortName, 32, "\\\\.\\%s", pszComPort);
  hComm = CreateFile(pszFullPortName, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
  return hComm != INVALID_HANDLE_VALUE;
}


uint32_t WriteCom(char *pBuffer, uint32_t uLen)
{
    DWORD dwWritten = 0;
    if (!WriteFile(hComm, pBuffer, uLen, NULL, &osTX) && GetLastError() == ERROR_IO_PENDING)
        GetOverlappedResult(hComm, &osTX, &dwWritten, TRUE);
    return dwWritten;
}

bool GetRXByte(char &rxByte)
{
  bool bResult = false;

  DWORD  dwReadBytes;
  if (!bWaitingOnRx)
  {
    if (ReadFile(hComm, &rxByte, 1, &dwReadBytes, &osRX))
      bResult = true;
    else
      bWaitingOnRx = true;
  }
  else
  {
    DWORD dwRes = WaitForSingleObject(osRX.hEvent, 0);
    if (dwRes == WAIT_OBJECT_0)
    {
      GetOverlappedResult(hComm, &osRX, &dwReadBytes, FALSE);
      bResult = true;
      bWaitingOnRx = false;
    }
  }

  return bResult;
}

bool HandleRX()
{
  bool bResult = true;

  char  rxByte = 0;
  DWORD  dwReadBytes;
  if (!bWaitingOnRx)
  {
    while (ReadFile(hComm, &rxByte, 1, &dwReadBytes, &osRX))
      putchar(rxByte);

    if (GetLastError() == ERROR_IO_PENDING)
      bWaitingOnRx = true;
    else
      bResult = false;
  }
  else
  {
    DWORD dwRes = WaitForSingleObject(osRX.hEvent, 10);
    if (dwRes == WAIT_OBJECT_0)
    {
      if (GetOverlappedResult(hComm, &osRX, &dwReadBytes, FALSE))
      {
        putchar(rxByte);
        bWaitingOnRx = false;
      }
      else
        bResult = false;
    }
    else
      if (dwRes == WAIT_FAILED)
        bResult = false;
  }

  return bResult;
}

std::string GuessPortName()
{
  TCHAR targetPath[1024];

  for (int i = 1; i < 256; i++)
  {
    auto portName = "COM" + std::to_string(i);

    // just return the first USB serial
    if (QueryDosDevice(portName.c_str(), targetPath, 1024) && std::string(targetPath).find("USB") != std::string::npos)
      return portName;
  }

  return "";
}

void usleep(uint32_t uSecs)
{
  Sleep(uSecs / 1000);
}
#else

int fdCom = -1;

ssize_t WriteCom(char *pBuffer, uint32_t uLen)
{
  uint32_t uRemaining = uLen;
  bool bError = false;
  while (!bError && uRemaining)
  {
    ssize_t nWritten = write(fdCom, pBuffer + (uLen - uRemaining), uRemaining);
    if (nWritten == -1)
      bError = true;
    else
      uRemaining -= nWritten;
  }

  if (!bError)
    tcdrain(fdCom);

  return uLen - uRemaining;;
}

bool GetRXByte(char &rxByte)
{
  return read(fdCom, &rxByte, 1) == 1;
}

bool HandleRX()
{
  bool bResult = true;

  char ch;
  ssize_t res = read(fdCom, &ch, 1);
  if (res == 1)
    putchar(ch);
  else
    if ((res == -1) && (errno != EAGAIN))
      bResult = false;

  return bResult;
}

void CloseCom()
{
  close(fdCom);
  fdCom = -1;
}

bool OpenComPort(const char *pszComPort, bool bTestConnection = false)
{
  bool bComPortOpen = false;
  if (fdCom != -1)
    close(fdCom);

  fdCom = open(pszComPort, O_RDWR | O_NOCTTY | O_SYNC);
  if (fdCom >= 0)
  {
    int flags = fcntl(fdCom, F_GETFL, 0);
    fcntl(fdCom, F_SETFL, flags | O_NONBLOCK);

    struct termios tio;
    tcgetattr(fdCom, &tio);
    cfmakeraw(&tio);
    tcsetattr(fdCom, TCSANOW, &tio);

    if (bTestConnection)
    {
      uint32_t uAck;
      bComPortOpen = Get32BlitInfo(uAck);
      if (!bComPortOpen)
        CloseCom();
    }
    else
      bComPortOpen = true;
  }
  return bComPortOpen;
}

std::string GuessPortName()
{
#ifdef __linux__
  // look for a serial device with "32Blit" in its name
  std::string sSearchDir = "/dev/serial/by-id";

  DIR *pDir = opendir(sSearchDir.c_str());

  if(!pDir)
    return "";

  struct dirent *pEntry;

  while((pEntry = readdir(pDir)))
  {
    std::string sName(pEntry->d_name);
    if(sName.find("32Blit") != std::string::npos)
      return sSearchDir + "/" + sName;
  }

  return "";

#elif __APPLE__
  auto classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue);
  if(!classesToMatch)
    return "";

  mach_port_t masterPort;
  auto kernResult = IOMasterPort(MACH_PORT_NULL, &masterPort);
  if(kernResult != KERN_SUCCESS)
    return "";

  io_iterator_t matchingServices;
  kernResult = IOServiceGetMatchingServices(masterPort, classesToMatch, &matchingServices);
  if(kernResult != KERN_SUCCESS)
    return "";

  io_object_t portService;
  char devicePath[1024] = {};
  bool found = false;

  while((portService = IOIteratorNext(matchingServices)) && !found)
  {
    // check product string
    auto productString = (CFStringRef)IORegistryEntrySearchCFProperty(portService, kIOServicePlane, CFSTR(kUSBProductString), kCFAllocatorDefault, kIORegistryIterateRecursively | kIORegistryIterateParents);

    if(!productString)
    {
      IOObjectRelease(portService);
      continue;
    }

    if(CFStringCompare(productString, CFSTR("32Blit CDC"), 0) != 0)
    {
      // not a blit
      CFRelease(productString);
      IOObjectRelease(portService);
      continue;
    }

    CFRelease(productString);

    // get device path
    auto devicePathAsCFString = (CFStringRef)IORegistryEntryCreateCFProperty(portService, CFSTR(kIOCalloutDeviceKey), kCFAllocatorDefault, 0);
    if(devicePathAsCFString)
    {
      if(CFStringGetCString(devicePathAsCFString, devicePath, 1024, kCFStringEncodingASCII))
        found = true;

      CFRelease(devicePathAsCFString);
    }

    IOObjectRelease(portService);
  }

  return std::string(devicePath);
#else
  // TODO: macOS
  return "";
#endif
}

#endif

bool WaitForHeader()
{
  bool    bHeaderFound = false;
  bool    bTimedOut = false;

  char    header[] = "32BL";
  uint8_t uHeaderPos = 0;

  clock_t uTimeoutClk = CLOCKS_PER_SEC * 1 + clock();

  while (!bHeaderFound && !bTimedOut)
  {
    char ch;
    if (GetRXByte(ch))
    {
      if (ch == header[uHeaderPos])
      {
        uHeaderPos++;
        bHeaderFound = (uHeaderPos == 4);
      }
      else
        uHeaderPos = 0;
    }
    else
      bTimedOut = clock() > uTimeoutClk;
  }

  return bHeaderFound;
}

bool GetFourCC(uint32_t &uFourCC)
{
  bool    bFourCCFound = false;
  bool    bTimedOut = false;

  char    buffer[4];
  uint8_t uBufferPos = 0;

  clock_t uTimeoutClk = CLOCKS_PER_SEC + clock();

  while (!bFourCCFound && !bTimedOut)
  {
    char ch;
    if (GetRXByte(ch))
    {
      buffer[uBufferPos++] = ch;
      bFourCCFound = (uBufferPos == 4);
    }
    else
      bTimedOut = clock() > uTimeoutClk;
  }

  if (bFourCCFound)
    uFourCC = (((((buffer[3] << 8) | buffer[2]) << 8) | buffer[1]) << 8) | buffer[0];
  return bFourCCFound;
}

bool Get32BlitInfo(uint32_t &uAck)
{
  bool bResult = false;

  char rstCommand[] = "32BLINFO";
  ssize_t res = WriteCom(rstCommand, 8);
  if (res != 8)
  {
    int shit = errno;
    printf("errno=%d\n", shit);
  }

  if (WaitForHeader())
    bResult = GetFourCC(uAck);

  return bResult;
}



bool ResetIfNeeded(const char *pszComPort)
{
  bool bResetNeeded = false;
  bool bFound32Blit = false;

  printf("Getting info from 32Blit...");

  uint32_t uAck;
  if (Get32BlitInfo(uAck))
  {
    switch (uAck)
    {
    case FourCCMake<'_', 'E', 'X', 'T'>::value:
      printf("Reset needed.\n");
      bResetNeeded = true;
      bFound32Blit = true;
      break;

    case FourCCMake<'_', 'I', 'N', 'T'>::value:
      printf("No reset needed.\n");
      bFound32Blit = true;
      break;

    default:
      printf("ERROR: Failed to get ack info from 32Blit, you may need a manual reset.\n");
      break;
    }
  }
  else
    printf("ERROR: Failed to get info header from 32Blit, you may need a manual reset.\n");

  if (bResetNeeded)
  {
    printf("Resetting 32Blit and waiting for USB connection, please wait...\n");
    // need to reset 32blit
    char rstCommand[] = "32BL_RST";
    WriteCom(rstCommand, (uint32_t)strlen(rstCommand));
    CloseCom();

    // wait for reconnect
    bool bReconnected = false;
    while (!bReconnected)
    {
      usleep(250000);
      bReconnected = OpenComPort(pszComPort, true);
    }
    printf("Reconnected to 32Blit after reset.\n");
  }

  return bFound32Blit;
}

int main(int argc, char *argv[])
{
  if (argc < 3)
  {
    usage();
    exit(1);
  }

  const char *pszProcess = argv[1];
  std::string sComPort = argv[2];
  const char *pszBinPath = nullptr;
  const char *pszBinFile = nullptr;
  bool bShouldReconnect = false;

  if (argc >= 4)
  {
    pszBinPath = argv[3];
    pszBinFile = getFileName(pszBinPath);
  }

  const uint32_t *puProcess = (uint32_t *)pszProcess;
  if (*puProcess != FourCCMake<'P', 'R', 'O', 'G'>::value && *puProcess != FourCCMake<'S', 'A', 'V', 'E'>::value && *puProcess != FourCCMake<'_', 'R', 'S', 'T'>::value)
  {
    usage();
    printf("ERROR <process> is %s, must be _RST, PROG or SAVE\n", pszProcess);
    exit(2);
  }
  else
  {
    if (*puProcess != FourCCMake<'_', 'R', 'S', 'T'>::value && argc < 4)
    {
      usage();
      exit(1);
    }
  }

  for(int i = 4; i < argc; i++)
  {
    std::string sArg(argv[i]);

    if(sArg == "--reconnect")
      bShouldReconnect = true;
  }

  bool bComPortOpen = false;

  if(sComPort == "AUTO")
  {
    auto sDetectedPort = GuessPortName();
    if(sDetectedPort.empty())
      printf("Failed to autodetect port\n");
    else
    {
      printf("Detected port as: %s\n", sDetectedPort.c_str());
      sComPort = sDetectedPort;
    }
  }

  bComPortOpen = OpenComPort(sComPort.c_str());

  if (!bComPortOpen)
  {
    usage();
    printf("ERROR <comport> Cannot open %s\n", sComPort.c_str());
    exit(6);
  }

  //while (1)
  //{
  //  char ch;
  //  if (GetRXByte(ch))
  //    putchar(ch);
  //  //HandleRX();
  //}

  // _RST
  if (!pszBinPath)
  {
    char header[1024];
    snprintf(header, 1024, "32BL%s%c", pszProcess, 0);
    size_t uLen = strlen(header) + 1;
    WriteCom(header, (uint32_t)uLen);
    CloseCom();
    exit(0);
  }

  FILE *pfBin = fopen(pszBinPath, "rb");
  if (!pfBin)
  {
    usage();
    printf("ERROR <binfile> Cannot open %s\n", pszBinPath);
    CloseCom();
    exit(5);
  }

  fseek(pfBin, 0L, SEEK_END);
  long nSize = ftell(pfBin);
  fseek(pfBin, 0L, SEEK_SET);

  if (nSize < 1)
  {
    usage();
    printf("ERROR <binfile> contains no data.");
    CloseCom();
    exit(3);
  }

  if (!ResetIfNeeded(sComPort.c_str()))
    exit(0);

  // check we can still talk to 32blit
  bool bAlive = false;
  while (!bAlive)
  {
    uint32_t uAck;
    if ((Get32BlitInfo(uAck)) && (uAck == FourCCMake<'_', 'I', 'N', 'T'>::value))
      bAlive = true;
    else
    {
      printf("Cannot talk to 32Blit, trying reconnect\n");
      // try to reconnect
      bComPortOpen = OpenComPort(sComPort.c_str());
    }
  }

  printf("Sending binary file ");
  char header[1024];
  snprintf(header, 1024, "32BL%s%s%c%ld%c", pszProcess, pszBinFile, '*', nSize, '*');
  size_t uLen = strlen(header);
  snprintf(header, 1024, "32BL%s%s%c%ld%c", pszProcess, pszBinFile, 0, nSize, 0);
  if (WriteCom(header, (uint32_t)uLen) != (ssize_t)uLen)
  {
    printf("Error: Failed to write header to 32Blit.\n");
    CloseCom();
    exit(0);
  }

  char buffer[64];
  bool bFinishedTX = false;

  long nTotalWritten = 0;
  long nTotalRead = 0;
  uint32_t uProgressCount = 20;
  while (!bFinishedTX)
  {
    // TX
    size_t uRead = fread(buffer, 1, 64, pfBin);
    nTotalRead += uRead;
    if (uRead)
    {
      ssize_t nWritten = WriteCom(buffer, (uint32_t)uRead);
      if (nWritten == (ssize_t)uRead)
        nTotalWritten += nWritten;
      else
      {
        printf("Error: failed to write data.\n");
        bFinishedTX = true;
      }
    }
    else
    {
      printf("\n");
      fclose(pfBin);
      bFinishedTX = true;
    }

    if (uProgressCount-- == 0)
    {
      uProgressCount = 20;
      putchar('*');
      fflush(stdout);
    }
  }

  // RX
  if (nTotalWritten != nSize)
  {
    printf("ERROR Incorrect number of bytes written, wrote %ld expected %ld\n", nTotalWritten, nSize);
    CloseCom();
    exit(0);
  }

  printf("Sending complete.\n");
  // Add a short delay to avoid PROG and SAVE hanging at 99% complete
  // See https://github.com/pimoroni/32blit-beta/pull/154
#ifdef WIN32
  Sleep(1000);
#else
  sleep(1);
#endif
  if (*puProcess == FourCCMake<'P', 'R', 'O', 'G'>::value && bShouldReconnect)
  {
    printf("Waiting for USB connection for debug logging, please wait...\n");
    // wait for reconnect
    bool bReconnected = false;
    while (!bReconnected)
    {
      usleep(250000);
      bReconnected = OpenComPort(sComPort.c_str());
      if (bReconnected)
      {
        uint32_t uAck;
        bReconnected = Get32BlitInfo(uAck);
      }
    }
    printf("Connected to 32Blit.\n");

    while (true)
    {
      if (!HandleRX())
      {
        CloseCom();
        printf("USB Connection lost, attempting to reconnect, please wait...\n");
        // wait for reconnect
        bool bReconnected = false;
        while (!bReconnected)
        {
          usleep(250000);
          bReconnected = OpenComPort(sComPort.c_str());
        }
        printf("Reconnected to 32Blit.\n");
      }
    }
  }

  CloseCom();
  exit(0);
}
