#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <tuple>

#include "hardware/flash.h"

#include "usb.hpp"
#include "blit_launch.hpp"
#include "multiplayer.hpp"
#include "overlay.hpp"

#include "fatfs_blit_api.hpp"

#include "engine/engine.hpp"
#include "executable.hpp"

#define MAX_FILENAME 256+1
#define MAX_FILELEN 16+1

void init();

static uint8_t cur_header[8];
static int header_pos = 0;
static CDCCommand *cur_command = nullptr;

static constexpr uint32_t to_cmd_id(const char str[4]) {
  return str[0] | str[1] << 8 | str[2] << 16 | str[3] << 24;
}

class CDCParseBuffer final {
public:
  void reset() {
    offset = 0;
  }

  uint8_t *get_data() {
    return buffer;
  }

  uint8_t *get_current_ptr() {
    return buffer + offset;
  }

  void add_read(uint32_t count) {
    offset += count;
    assert(offset <= buffer_size);
  }

  uint32_t get_offset() const {
    return offset;
  }

private:
  static const size_t buffer_size = std::max((unsigned)std::max(MAX_FILELEN, MAX_FILENAME), FLASH_PAGE_SIZE);
  uint8_t buffer[buffer_size];

  uint32_t offset = 0;
};

/*
  Helper to read a string
  returns Done when the string is ready (in buf.get_ptr())
  returns Error when we've reached the max length without a terminator
  returns Continue when there is currently no more data to read
*/
static CDCCommand::Status cdc_read_string(CDCParseBuffer &buf, uint32_t max_len) {
  while(true) {
    auto buf_ptr = buf.get_current_ptr();

    if(!usb_cdc_read(buf_ptr, 1))
      return CDCCommand::Status::Continue;

    // end of string
    if(*buf_ptr == 0)
      return CDCCommand::Status::Done;

    buf.add_read(1);

    // too long
    if(buf.get_offset() == max_len)
      return CDCCommand::Status::Error;
  }
}

// helper in an attempt to keep commands more generic...
static void cdc_command_progress(const char *message, uint32_t progress, uint32_t total) {
  set_render_overlay_enabled(message != nullptr || total);

  // null message preserves the old one
  if(message)
    set_overlay_message(message);

  set_overlay_progress(progress, total);
}

class CDCProgCommand final : public CDCCommand {
public:
  CDCProgCommand(CDCParseBuffer &buf) : buf(buf) {}

  void init() override {
    parse_state = ParseState::Filename;
    buf.reset();
  }

  Status update() override {

    while(true) {
      switch(parse_state) {
        case ParseState::Filename: {
          auto status = cdc_read_string(buf, MAX_FILENAME);
          if(status == Status::Done) {
            // setup progress message
            char message_buf[300];
            snprintf(message_buf, sizeof(message_buf), "Saving %s to flash...", buf.get_data());
            cdc_command_progress(message_buf, 0, 0);

            parse_state = ParseState::Length;
            buf.reset();
            continue;
          }

          return status;
        }

        case ParseState::Length: {
          auto status = cdc_read_string(buf, MAX_FILELEN);
          if(status == Status::Done) {
            auto file_len = strtoul((const char *)buf.get_data(), nullptr, 10);
            parse_state = ParseState::Data;
            buf.reset();

            cdc_command_progress(nullptr, 0, file_len);

            writer.init(file_len);
            continue;
          }

          return status;
        }

        case ParseState::Data: {
          // read data
          auto max = std::min(uint32_t(FLASH_PAGE_SIZE), writer.get_remaining()) - buf.get_offset();
          auto read = usb_cdc_read(buf.get_current_ptr(), max);

          if(!read)
            return Status::Continue;

          buf.add_read(read);

          // got full page or final part of file
          auto buf_off = buf.get_offset();
          if(buf_off == FLASH_PAGE_SIZE || buf_off == writer.get_remaining()) {
            if(!writer.write(buf.get_data(), buf_off)) {
              cdc_command_progress(nullptr, 0, 0); // clear progress
              return Status::Error;
            }

            cdc_command_progress(nullptr, writer.get_offset(), writer.get_length());

            buf.reset();
          }

          // end of file
          if(writer.get_remaining() == 0) {
            cdc_command_progress(nullptr, 0, 0); // clear progress

            writer.cleanup_duplicates();

            // send response
            auto block = writer.get_flash_offset() >> 16;
            uint8_t res_data[]{'3', '2', 'B', 'L', '_', '_', 'O', 'K', uint8_t(block), uint8_t(block >> 8)};
            usb_cdc_write(res_data, sizeof(res_data));
            usb_cdc_flush_write();

            // reinit loader
            close_open_files();
            ::init();

            return Status::Done;
          }

          break;
        }
      }
    }

    return Status::Continue;
  }

  enum class ParseState {
    Filename,
    Length,
    Data
  } parse_state = ParseState::Filename;

  CDCParseBuffer &buf;

  BlitWriter writer;
};

class CDCSaveCommand final : public CDCCommand {
public:
  CDCSaveCommand(CDCParseBuffer &buf) : buf(buf) {}

  void init() override {
    parse_state = ParseState::Filename;
    file_offset = 0;
    buf.reset();
  }

  Status update() override {
    while(true) {
      switch(parse_state) {
        case ParseState::Filename: {
          auto status = cdc_read_string(buf, MAX_FILENAME);
          if(status == Status::Done) {
            auto filename = (const char *)buf.get_data();

            file = blit::api.open_file(filename, blit::OpenMode::write);
            if(!file) {
              blit::debugf("Failed to open %s", filename);
              return Status::Error;
            }

            // setup progress message
            char message_buf[300];
            snprintf(message_buf, sizeof(message_buf), "Saving %s...", filename);
            cdc_command_progress(message_buf, 0, 0);

            parse_state = ParseState::Length;
            buf.reset();
            continue;
          }

          return status;
        }

        case ParseState::Length: {
          auto status = cdc_read_string(buf, MAX_FILELEN);
          if(status == Status::Done) {
            file_length = strtoul((const char *)buf.get_data(), nullptr, 10);

            cdc_command_progress(nullptr, 0, file_length);

            parse_state = ParseState::Data;
            buf.reset();
            continue;
          }

          return status;
        }

        case ParseState::Data: {
          // read data
          auto max = std::min(uint32_t(FLASH_PAGE_SIZE), file_length - file_offset);
          auto read = usb_cdc_read(buf.get_current_ptr(), max);

          if(!read)
            return Status::Continue;

          // write whatever we got, the fs is going to buffer anyway
          auto written = blit::api.write_file(file, file_offset, read, (const char *)buf.get_data());
          if(written != read) {
            blit::api.close_file(file);
            cdc_command_progress(nullptr, 0, 0); // clear progress
            return Status::Error;
          }

          file_offset += read;

          cdc_command_progress(nullptr, file_offset, file_length);

          // end of file
          if(file_offset == file_length) {
            blit::api.close_file(file);
            cdc_command_progress(nullptr, 0, 0); // clear progress

            // send response
            uint8_t res_data[]{'3', '2', 'B', 'L', '_', '_', 'O', 'K'};
            usb_cdc_write(res_data, sizeof(res_data));
            usb_cdc_flush_write();

            return Status::Done;
          }

          break;
        }
      }
    }

    return Status::Continue;
  }

  enum class ParseState {
    Filename,
    Length,
    Data
  } parse_state = ParseState::Filename;

  CDCParseBuffer &buf;

  void *file = nullptr;
  uint32_t file_length = 0, file_offset = 0;
};

class CDCListCommand final : public CDCCommand {
  void init() override {
  }

  Status update() override {
    blit::api.list_installed_games([](const uint8_t *ptr, uint32_t block, uint32_t size) {
      // bit of a mismatch between the API and the CDC API
      // this wants offset in bytes and the size WITHOUT metadata
      uint32_t offset_bytes = block * game_block_size;
      uint32_t header_size = ((BlitGameHeader *)ptr)->end & 0x1FFFFFF;

      usb_cdc_write((uint8_t *)&offset_bytes, sizeof(uint32_t));
      usb_cdc_write((uint8_t *)&header_size, sizeof(uint32_t));
      usb_cdc_flush_write();

      // write metadata if found
      auto meta = ptr + header_size;

      if(memcmp(meta, "BLITMETA", 8) == 0) {
        auto meta_size = *(uint16_t *)(meta + 8);
        usb_cdc_write(meta, meta_size + 10);
      } else {
        // no meta, write header + 0 len
        usb_cdc_write((const uint8_t *)"BLITMETA\0", 10);
      }
      usb_cdc_flush_write();
    });

    // end marker
    uint32_t end = 0xFFFFFFFF;
    usb_cdc_write((uint8_t *)&end, sizeof(uint32_t));
    usb_cdc_flush_write();

    return Status::Done;
  }
};

class CDCLaunchCommand final : public CDCCommand {
public:
  CDCLaunchCommand(CDCParseBuffer &buf) : buf(buf) {}

  void init() override {
    buf.reset();
  }

  Status update() override {
    auto status = cdc_read_string(buf, MAX_FILENAME);

    if(status == Status::Done)
      blit::api.launch((const char *)buf.get_data());

    return status;
  }

  CDCParseBuffer &buf;
};

class CDCEraseCommand final : public CDCCommand {
public:
  CDCEraseCommand(CDCParseBuffer &buf) : buf(buf) {}

  void init() override {
    buf.reset();
  }

  Status update() override {
    while(true) {
        auto buf_ptr = buf.get_current_ptr();
        if(!usb_cdc_read(buf_ptr, 1))
          return Status::Continue;

        buf.add_read(1);

        // end of word
        if(buf.get_offset() == 4) {
          blit::api.erase_game(*(uint32_t *)buf.get_data());
          return Status::Done;
        }
    }

    return Status::Continue;
  }

  CDCParseBuffer &buf;
};


static CDCHandshakeCommand handshake_command;
static CDCUserCommand user_command;

#if defined(BUILD_LOADER) && !defined(USB_HOST)
#define FLASH_COMMANDS
static CDCParseBuffer parse_buffer;
static CDCProgCommand prog_command(parse_buffer);
static CDCSaveCommand save_command(parse_buffer);
static CDCListCommand list_command;
static CDCLaunchCommand launch_command(parse_buffer);
static CDCEraseCommand erase_command(parse_buffer);
#endif

const std::tuple<uint32_t, CDCCommand *> cdc_commands[]{
  {to_cmd_id("MLTI"), &handshake_command},
  {to_cmd_id("USER"), &user_command},

#ifdef FLASH_COMMANDS
  {to_cmd_id("PROG"), &prog_command},
  {to_cmd_id("SAVE"), &save_command},
  {to_cmd_id("__LS"), &list_command},
  {to_cmd_id("LNCH"), &launch_command},
  {to_cmd_id("ERSE"), &erase_command},
#endif
};

void usb_cdc_update() {
  while(usb_cdc_read_available()) {
    // command in progress
    if(cur_command) {
      auto res = cur_command->update();

      if(res == CDCCommand::Status::Continue) {
        break;
      } else {
        // done/error
        cur_command = nullptr;
      }

      continue;
    }

    // match header
    if(header_pos < 8) {
      usb_cdc_read(cur_header + header_pos, 1);

      const char *expected = "32BL";
      if(header_pos >= 4 || cur_header[header_pos] == expected[header_pos])
        header_pos++;
      else
        header_pos = 0;
    } else {

      // got header
      auto command_id = to_cmd_id((char *)cur_header + 4);

      // find command
      for(auto &cmd : cdc_commands) {
        if(std::get<0>(cmd) == command_id) {
          cur_command = std::get<1>(cmd);
          break;
        }
      }

      if(!cur_command)
        printf("got: %c%c%c%c%c%c%c%c\n", cur_header[0], cur_header[1], cur_header[2], cur_header[3], cur_header[4], cur_header[5], cur_header[6], cur_header[7]);
      else
        cur_command->init();

      header_pos = 0;
    }
  }
}
