#pragma once

#include <assert.h>
#include <ast_video_types.hpp>
#include <iostream>
#include <mutex>
#include <vector>
#include <boost/asio.hpp>

namespace AstVideo {

//
// Cursor struct is used in User Mode
//
typedef struct _cursor_attribution_tag {
  unsigned int posX;
  unsigned int posY;
  unsigned int cur_width;
  unsigned int cur_height;
  unsigned int cur_type;  // 0:mono 1:color 2:disappear cursor
  unsigned int cur_change_flag;
} AST_CUR_ATTRIBUTION_TAG;

//
// For storing Cursor Information
//
typedef struct _cursor_tag {
  AST_CUR_ATTRIBUTION_TAG attr;
  // unsigned char     icon[MAX_CUR_OFFSETX*MAX_CUR_OFFSETY*2];
  unsigned char *icon;  //[64*64*2];
} AST_CURSOR_TAG;

//
// For select image format, i.e. 422 JPG420, 444 JPG444, lumin/chrom table, 0
// ~ 11, low to high
//
typedef struct _video_features {
  short jpg_fmt;  // 422:JPG420, 444:JPG444
  short lumin_tbl;
  short chrom_tbl;
  short tolerance_noise;
  int w;
  int h;
  unsigned char *buf;
} FEATURES_TAG;

//
// For configure video engine control registers
//
typedef struct _image_info {
  short do_image_refresh;  // Action 0:motion 1:fullframe 2:quick cursor
  char qc_valid;           // quick cursor enable/disable
  unsigned int len;
  int crypttype;
  char cryptkey[16];
  union {
    FEATURES_TAG features;
    AST_CURSOR_TAG cursor_info;
  } parameter;
} IMAGE_INFO;

class SimpleVideoPuller {
 public:
  SimpleVideoPuller() : image_info(){};

  void initialize() {
    std::cout << "Opening /dev/video\n";
    video_fd = open("/dev/video", O_RDWR);
    if (!video_fd) {
      std::cout << "Failed to open /dev/video\n";
      throw std::runtime_error("Failed to open /dev/video");
    }
    std::cout << "Opened successfully\n";
  }

  RawVideoBuffer read_video() {
    assert(video_fd != 0);
    RawVideoBuffer raw;

    image_info.do_image_refresh = 1;  // full frame refresh
    image_info.qc_valid = 0;          // quick cursor disabled
    image_info.parameter.features.buf =
        reinterpret_cast<unsigned char *>(raw.buffer.data());
    image_info.crypttype = -1;
    std::cout << "Writing\n";

    int status;
    /*
    status = write(video_fd, reinterpret_cast<char*>(&image_info),
                        sizeof(image_info));
    if (status != sizeof(image_info)) {
      std::cout << "Write failed.  Return: " << status << "\n";
      perror("perror output:");
    }

    std::cout << "Write done\n";
    */
    std::cout << "Reading\n";
    status = read(video_fd, reinterpret_cast<char *>(&image_info),
                  sizeof(image_info));
    std::cout << "Done reading\n";

    if (status != 0) {
      std::cerr << "Read failed with status " << status << "\n";
    }

    raw.buffer.resize(image_info.len);

    raw.height = image_info.parameter.features.h;
    raw.width = image_info.parameter.features.w;
    if (image_info.parameter.features.jpg_fmt == 422) {
      raw.mode = YuvMode::YUV420;
    } else {
      raw.mode = YuvMode::YUV444;
    }
    return raw;
  }

 private:
  int video_fd;
  IMAGE_INFO image_info;
};

#if defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
class AsyncVideoPuller {
 public:
  typedef std::function<void(RawVideoBuffer &)> video_callback;

  AsyncVideoPuller(boost::asio::io_service &io_service)
      : image_info(), dev_video(io_service, open("/dev/video", O_RDWR)) {
    videobuf = std::make_shared<RawVideoBuffer>();

    image_info.do_image_refresh = 1;  // full frame refresh
    image_info.qc_valid = 0;          // quick cursor disabled
    image_info.parameter.features.buf =
        reinterpret_cast<unsigned char *>(videobuf->buffer.data());
    image_info.crypttype = -1;
  };

  void register_callback(video_callback &callback) {
    std::lock_guard<std::mutex> lock(callback_mutex);
    callbacks.push_back(callback);
    start_read();
  }

  void start_read() {
    auto mutable_buffer = boost::asio::buffer(&image_info, sizeof(image_info));
    boost::asio::async_read(
        dev_video, mutable_buffer, [this](const boost::system::error_code &ec,
                                          std::size_t bytes_transferred) {
          if (ec) {
            std::cerr << "Read failed with status " << ec << "\n";
          } else {
            this->read_done();
          }
        });
  }

  void read_done() {
    std::cout << "Done reading\n";
    videobuf->buffer.resize(image_info.len);

    videobuf->height = image_info.parameter.features.h;
    videobuf->width = image_info.parameter.features.w;
    if (image_info.parameter.features.jpg_fmt == 422) {
      videobuf->mode = YuvMode::YUV420;
    } else {
      videobuf->mode = YuvMode::YUV444;
    }
    std::lock_guard<std::mutex> lock(callback_mutex);
    for (auto &callback : callbacks) {
      // TODO(ed) call callbacks async and double buffer frames
      callback(*videobuf);
    }
  }

 private:
  std::shared_ptr<RawVideoBuffer> videobuf;
  boost::asio::posix::stream_descriptor dev_video;
  IMAGE_INFO image_info;
  std::mutex callback_mutex;
  std::vector<video_callback> callbacks;
};
#endif  // defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
}
