#include <boost/endian/arithmetic.hpp>
#include <string>

#include <crow/bmc_app_type.hpp>

#include <video.h>

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
};

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++] = 0;  // 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;

void request_routes(BmcAppType& 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 {
          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 = 640;
            server_init_msg.framebuffer_height = 480;
            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));

                    if (!msg->incremental) {
                      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 = msg->width;
                      this_rect.height = msg->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);

                      for (unsigned int x_index = 0; x_index < this_rect.width;
                           x_index++) {
                        for (unsigned int y_index = 0;
                             y_index < this_rect.height; y_index++) {
                          this_rect.data.push_back(
                              static_cast<uint8_t>(0));  // Blue
                          this_rect.data.push_back(
                              static_cast<uint8_t>(0));  // Green
                          this_rect.data.push_back(static_cast<uint8_t>(
                              x_index * 0xFF / msg->width));  // RED
                          this_rect.data.push_back(
                              static_cast<uint8_t>(0));  // UNUSED
                        }
                      }

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

                      conn.send_binary(serialized);
                    }
                  }

                }

                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;
        }

      });
}
}
}