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

#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::VideoPuller 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;
        }

      });
}
}
}