#include <string>
#include <crow/app.h>
#include <boost/endian/arithmetic.hpp>

#include <ast_jpeg_decoder.hpp>
#include <ast_video_puller.hpp>

namespace crow {
namespace kvm {

static const std::string rfb_3_3_version_string = "RFB 003.003\n";
static const std::string rfb_3_7_version_string = "RFB 003.007\n";
static const std::string rfb_3_8_version_string = "RFB 003.008\n";

enum class RfbAuthScheme : uint8_t {
  connection_failed = 0,
  no_authentication = 1,
  vnc_authentication = 2
};

struct pixel_format_struct {
  boost::endian::big_uint8_t bits_per_pixel;
  boost::endian::big_uint8_t depth;
  boost::endian::big_uint8_t is_big_endian;
  boost::endian::big_uint8_t is_true_color;
  boost::endian::big_uint16_t red_max;
  boost::endian::big_uint16_t green_max;
  boost::endian::big_uint16_t blue_max;
  boost::endian::big_uint8_t red_shift;
  boost::endian::big_uint8_t green_shift;
  boost::endian::big_uint8_t blue_shift;
  boost::endian::big_uint8_t pad1;
  boost::endian::big_uint8_t pad2;
  boost::endian::big_uint8_t pad3;
};

struct server_initialization_msg {
  boost::endian::big_uint16_t framebuffer_width;
  boost::endian::big_uint16_t framebuffer_height;
  pixel_format_struct pixel_format;
  boost::endian::big_uint32_t name_length;
};

enum class client_to_server_msg_type : uint8_t {
  set_pixel_format = 0,
  fix_color_map_entries = 1,
  set_encodings = 2,
  framebuffer_update_request = 3,
  key_event = 4,
  pointer_event = 5,
  client_cut_text = 6
};

enum class server_to_client_message_type : uint8_t {
  framebuffer_update = 0,
  set_color_map_entries = 1,
  bell_message = 2,
  server_cut_text = 3
};

struct set_pixel_format_msg {
  boost::endian::big_uint8_t pad1;
  boost::endian::big_uint8_t pad2;
  boost::endian::big_uint8_t pad3;
  pixel_format_struct pixel_format;
};

struct frame_buffer_update_req {
  boost::endian::big_uint8_t incremental;
  boost::endian::big_uint16_t x_position;
  boost::endian::big_uint16_t y_position;
  boost::endian::big_uint16_t width;
  boost::endian::big_uint16_t height;
};

struct key_event_msg {
  boost::endian::big_uint8_t down_flag;
  boost::endian::big_uint8_t pad1;
  boost::endian::big_uint8_t pad2;
  boost::endian::big_uint32_t key;
};

struct pointer_event_msg {
  boost::endian::big_uint8_t button_mask;
  boost::endian::big_uint16_t x_position;
  boost::endian::big_uint16_t y_position;
};

struct client_cut_text_msg {
  std::vector<uint8_t> data;
};

enum class encoding_type : uint32_t {
  raw = 0x00,
  copy_rectangle = 0x01,
  rising_rectangle = 0x02,
  corre = 0x04,
  hextile = 0x05,
  zlib = 0x06,
  tight = 0x07,
  zlibhex = 0x08,
  ultra = 0x09,
  zrle = 0x10,
  zywrle = 0x011,
  cache_enable = 0xFFFF0001,
  xor_enable = 0xFFFF0006,
  server_state_ultranvc = 0xFFFF8000,
  enable_keep_alive = 0xFFFF8001,
  enableftp_protocol_version = 0xFFFF8002,
  tight_compress_level_0 = 0xFFFFFF00,
  tight_compress_level_9 = 0xFFFFFF09,
  x_cursor = 0xFFFFFF10,
  rich_cursor = 0xFFFFFF11,
  pointer_pos = 0xFFFFFF18,
  last_rect = 0xFFFFFF20,
  new_framebuffer_size = 0xFFFFFF21,
  tight_quality_level_0 = 0xFFFFFFE0,
  tight_quality_level_9 = 0xFFFFFFE9
};

struct framebuffer_rectangle {
  boost::endian::big_uint16_t x;
  boost::endian::big_uint16_t y;
  boost::endian::big_uint16_t width;
  boost::endian::big_uint16_t height;
  boost::endian::big_uint32_t encoding;
  std::vector<uint8_t> data;
};

struct framebuffer_update_msg {
  boost::endian::big_uint8_t message_type;
  std::vector<framebuffer_rectangle> rectangles;
};

std::string serialize(const framebuffer_update_msg& msg) {
  // calculate the size of the needed vector for serialization
  size_t vector_size = 4;
  for (const auto& rect : msg.rectangles) {
    vector_size += 12 + rect.data.size();
  }

  std::string serialized(vector_size, 0);

  size_t i = 0;
  serialized[i++] = static_cast<char>(
      server_to_client_message_type::framebuffer_update);  // Type
  serialized[i++] = 0;                                     // Pad byte
  boost::endian::big_uint16_t number_of_rectangles = msg.rectangles.size();
  std::memcpy(&serialized[i], &number_of_rectangles,
              sizeof(number_of_rectangles));
  i += sizeof(number_of_rectangles);

  for (const auto& rect : msg.rectangles) {
    // copy the first part of the struct
    size_t buffer_size =
        sizeof(framebuffer_rectangle) - sizeof(std::vector<uint8_t>);
    std::memcpy(&serialized[i], &rect, buffer_size);
    i += buffer_size;

    std::memcpy(&serialized[i], rect.data.data(), rect.data.size());
    i += rect.data.size();
  }

  return serialized;
}

enum class VncState {
  UNSTARTED,
  AWAITING_CLIENT_VERSION,
  AWAITING_CLIENT_AUTH_METHOD,
  AWAITING_CLIENT_INIT_msg,
  MAIN_LOOP
};

class connection_metadata {
 public:
  connection_metadata(void) : vnc_state(VncState::UNSTARTED){};

  VncState vnc_state;
};

typedef std::vector<connection_metadata> meta_list;
meta_list connection_states(10);

connection_metadata meta;

template <typename... Middlewares>
void request_routes(Crow<Middlewares...>& app) {
  CROW_ROUTE(app, "/kvmws")
      .websocket()
      .onopen([&](crow::websocket::connection& conn) {
        if (meta.vnc_state == VncState::UNSTARTED) {
          meta.vnc_state = VncState::AWAITING_CLIENT_VERSION;
          conn.send_binary(rfb_3_8_version_string);
        } else {  // SHould never happen
          conn.close();
        }

      })
      .onclose(
          [&](crow::websocket::connection& conn, const std::string& reason) {
            meta.vnc_state = VncState::UNSTARTED;
          })
      .onmessage([&](crow::websocket::connection& conn, const std::string& data,
                     bool is_binary) {
        switch (meta.vnc_state) {
          case VncState::AWAITING_CLIENT_VERSION: {
            LOG(DEBUG) << "Client sent: " << data;
            if (data == rfb_3_8_version_string ||
                data == rfb_3_7_version_string) {
              std::string auth_types{1,
                                     (uint8_t)RfbAuthScheme::no_authentication};
              conn.send_binary(auth_types);
              meta.vnc_state = VncState::AWAITING_CLIENT_AUTH_METHOD;
            } else if (data == rfb_3_3_version_string) {
              // TODO(ed)  Support older protocols
              meta.vnc_state = VncState::UNSTARTED;
              conn.close();
            } else {
              // TODO(ed)  Support older protocols
              meta.vnc_state = VncState::UNSTARTED;
              conn.close();
            }
          } break;
          case VncState::AWAITING_CLIENT_AUTH_METHOD: {
            std::string security_result{{0, 0, 0, 0}};
            if (data[0] == (uint8_t)RfbAuthScheme::no_authentication) {
              meta.vnc_state = VncState::AWAITING_CLIENT_INIT_msg;
            } else {
              // Mark auth as failed
              security_result[3] = 1;
              meta.vnc_state = VncState::UNSTARTED;
            }
            conn.send_binary(security_result);
          } break;
          case VncState::AWAITING_CLIENT_INIT_msg: {
            // Now send the server initialization
            server_initialization_msg server_init_msg;
            server_init_msg.framebuffer_width = 800;
            server_init_msg.framebuffer_height = 600;
            server_init_msg.pixel_format.bits_per_pixel = 32;
            server_init_msg.pixel_format.is_big_endian = 0;
            server_init_msg.pixel_format.is_true_color = 1;
            server_init_msg.pixel_format.red_max = 255;
            server_init_msg.pixel_format.green_max = 255;
            server_init_msg.pixel_format.blue_max = 255;
            server_init_msg.pixel_format.red_shift = 16;
            server_init_msg.pixel_format.green_shift = 8;
            server_init_msg.pixel_format.blue_shift = 0;
            server_init_msg.name_length = 0;
            LOG(DEBUG) << "size: " << sizeof(server_init_msg);
            // TODO(ed) this is ugly.  Crow should really have a span type
            // interface
            // to avoid the copy, but alas, today it does not.
            std::string s(reinterpret_cast<char*>(&server_init_msg),
                          sizeof(server_init_msg));
            LOG(DEBUG) << "s.size() " << s.size();
            conn.send_binary(s);
            meta.vnc_state = VncState::MAIN_LOOP;
          } break;
          case VncState::MAIN_LOOP: {
            if (data.size() >= sizeof(client_to_server_msg_type)) {
              auto type = static_cast<client_to_server_msg_type>(data[0]);
              LOG(DEBUG) << "Received client message type " << (uint32_t)type
                         << "\n";
              switch (type) {
                case client_to_server_msg_type::set_pixel_format: {
                } break;

                case client_to_server_msg_type::fix_color_map_entries: {
                } break;
                case client_to_server_msg_type::set_encodings: {
                } break;
                case client_to_server_msg_type::framebuffer_update_request: {
                  // Make sure the buffer is long enough to handle what we're
                  // about to do
                  if (data.size() >= sizeof(frame_buffer_update_req) +
                                         sizeof(client_to_server_msg_type)) {
                    auto msg = reinterpret_cast<const frame_buffer_update_req*>(
                        data.data() + sizeof(client_to_server_msg_type));

                    // Todo(ed) lifecycle of the video puller and decoder
                    // should be
                    // with the websocket, not recreated every time
                    AstVideo::SimpleVideoPuller p;
                    p.initialize();
                    auto out = p.read_video();
                    AstVideo::AstJpegDecoder d;
                    d.decode(out.buffer, out.width, out.height, out.mode,
                             out.y_selector, out.uv_selector);

                    framebuffer_update_msg buffer_update_msg;

                    // If the viewer is requesting a full update, force write
                    // of all pixels

                    framebuffer_rectangle this_rect;
                    this_rect.x = msg->x_position;
                    this_rect.y = msg->y_position;
                    this_rect.width = out.width;
                    this_rect.height = out.height;
                    this_rect.encoding =
                        static_cast<uint8_t>(encoding_type::raw);
                    LOG(DEBUG) << "Encoding is " << this_rect.encoding;
                    this_rect.data.reserve(this_rect.width * this_rect.height *
                                           4);
                    LOG(DEBUG) << "Width " << out.width << " Height "
                               << out.height;

                    for (int i = 0; i < out.width * out.height; i++) {
                      auto& pixel = d.OutBuffer[i];
                      this_rect.data.push_back(pixel.B);
                      this_rect.data.push_back(pixel.G);
                      this_rect.data.push_back(pixel.R);
                      this_rect.data.push_back(0);
                    }

                    buffer_update_msg.rectangles.push_back(
                        std::move(this_rect));
                    auto serialized = serialize(buffer_update_msg);

                    conn.send_binary(serialized);

                  }  // TODO(Ed) handle error

                }

                break;

                case client_to_server_msg_type::key_event: {
                } break;

                case client_to_server_msg_type::pointer_event: {
                } break;

                case client_to_server_msg_type::client_cut_text: {
                } break;

                default:
                  break;
              }
            }

          } break;
          case VncState::UNSTARTED:
            // Error?  TODO
            break;
        }

      });
}
}
}