#include <chrono>
#include <iostream>
#include <random>
#include "SDL.h"

#include "File.hpp"
#include "System.hpp"
#include "Input.hpp"
#include "32blit.hpp"
#include "UserCode.hpp"
#include "JPEG.hpp"
#include "Multiplayer.hpp"

#include "engine/api_private.hpp"

extern Input *blit_input;

// blit audio channels
static blit::AudioChannel channels[CHANNEL_COUNT];

int System::width = System::max_width;
int System::height = System::max_height;

// blit framebuffer memory
static uint8_t framebuffer[System::max_width * System::max_height * 3];
static blit::Pen palette[256];

// blit debug callback
void blit_debug(const char *message) {
	std::cout << message;
}

// blit screenmode callback
blit::ScreenMode _mode = blit::ScreenMode::lores;
static blit::ScreenMode requested_mode = blit::ScreenMode::lores;
static blit::PixelFormat cur_format = blit::PixelFormat::RGB;
static blit::PixelFormat requested_format = blit::PixelFormat::RGB;

blit::SurfaceInfo cur_surf_info;

static void set_screen_palette(const blit::Pen *colours, int num_cols) {
	memcpy(palette, colours, num_cols * sizeof(blit::Pen));
}

static bool set_screen_mode_format(blit::ScreenMode new_mode, blit::SurfaceTemplate &new_surf_template) {
  new_surf_template.data = framebuffer;

  if(new_surf_template.format == (blit::PixelFormat)-1)
    new_surf_template.format = blit::PixelFormat::RGB;

  blit::Size default_bounds(System::width, System::height);

  if(new_surf_template.bounds.empty())
    new_surf_template.bounds = default_bounds;

  switch(new_mode) {
    case blit::ScreenMode::lores:
      new_surf_template.bounds /= 2;
      break;
    case blit::ScreenMode::hires:
    case blit::ScreenMode::hires_palette:
      break;
  }

  if(new_surf_template.bounds != default_bounds && new_surf_template.bounds != default_bounds / 2)
    return false;

  switch(new_surf_template.format) {
    case blit::PixelFormat::RGB:
    case blit::PixelFormat::RGB565:
      break;
    case blit::PixelFormat::P:
      new_surf_template.palette = palette;
      break;

    default:
      return false;
  }

  requested_mode = new_mode;
  requested_format = new_surf_template.format;

  return true;
}

blit::SurfaceInfo &set_screen_mode(blit::ScreenMode new_mode) {
  blit::SurfaceTemplate temp{nullptr, {0, 0}, new_mode == blit::ScreenMode::hires_palette ? blit::PixelFormat::P : blit::PixelFormat::RGB};

  // won't fail for the modes used here
  set_screen_mode_format(new_mode, temp);

  cur_surf_info.data = temp.data;
  cur_surf_info.bounds = temp.bounds;
  cur_surf_info.format = temp.format;
  cur_surf_info.palette = temp.palette;

  return cur_surf_info;
}

// blit timer callback
std::chrono::steady_clock::time_point start;
uint32_t now() {
	auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start);
	return (uint32_t)elapsed.count();
}

// blit random callback
#ifdef __MINGW32__
// Windows/MinGW doesn't support a non-deterministic source of randomness, so we fall back upon the age-old time seed once more
// Without this, random_device() will always return the same number and thus our mersenne twister will always produce the same sequence.
std::mt19937 random_generator(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count());
#else
std::random_device random_device;
std::mt19937 random_generator(random_device());
#endif
std::uniform_int_distribution<uint32_t> random_distribution;
uint32_t blit_random() {
	return random_distribution(random_generator);
}


// us timer used by profiler

void enable_us_timer()
{
	// Enable/initialise timer
}

uint32_t get_us_timer()
{
	// get current time in us
	uint64_t ticksPerUs = SDL_GetPerformanceFrequency() / 1000000;
	return SDL_GetPerformanceCounter() / ticksPerUs;
}

uint32_t get_max_us_timer()
{
	// largest us value timer can produce for wrapping
	return UINT32_MAX;
}

/* Added a command line ability to specify a launch_path parameter. */
extern const char *launch_path;
static const char *get_launch_path() {
  return launch_path;
}

static blit::GameMetadata get_metadata() {
  blit::GameMetadata ret;

  ret.title = metadata_title;
  ret.author = metadata_author;
  ret.description = metadata_description;
  ret.version = metadata_version;
  ret.url = metadata_url;
  ret.category = metadata_category;

  return ret;
}

extern Multiplayer *blit_multiplayer;
bool blit_is_multiplayer_connected() {
	return blit_multiplayer->is_connected();
}

void blit_set_multiplayer_enabled(bool enabled) {
	blit_multiplayer->set_enabled(enabled);
}

void blit_send_message(const uint8_t *data, uint16_t length) {
	blit_multiplayer->send_message(data, length);
}

// blit API
static const blit::APIConst blit_api_const {
  blit::api_version_major, blit::api_version_minor,
  channels,

  ::set_screen_mode,
  ::set_screen_palette,

  ::now,
  ::blit_random,
  nullptr, // exit
  ::blit_debug,

  ::open_file,
  ::read_file,
  ::write_file,
  ::close_file,
  ::get_file_length,
  ::list_files,
  ::file_exists,
  ::directory_exists,
  ::create_directory,
  ::rename_file,
  ::remove_file,
  ::get_save_path,
  ::is_storage_available,

  ::enable_us_timer,
  ::get_us_timer,
  ::get_max_us_timer,

  blit_decode_jpeg_buffer,
  blit_decode_jpeg_file,

  nullptr, // launch
  nullptr, // erase_game
  nullptr, // get_type_handler_metadata

  ::get_launch_path,

  blit_is_multiplayer_connected,
  blit_set_multiplayer_enabled,
  blit_send_message,

  nullptr, // flash_to_tmp
  nullptr, // tmp_file_closed

  ::get_metadata,

  ::set_screen_mode_format,

  nullptr, // i2c_send
  nullptr, // i2c_recieve

  nullptr, // set_raw_cdc_enabled
  nullptr, // cdc_write
  nullptr, // cdc_read

  nullptr, // list_installed_games
  nullptr, // can_launch

  nullptr, // get_screen_data
  nullptr, // set_framebuffer
};

static blit::APIData blit_api_data;

namespace blit {
  const APIConst &api = blit_api_const;
  APIData &api_data = blit_api_data;
}

// SDL events
const Uint32 System::timer_event = SDL_RegisterEvents(2);
const Uint32 System::loop_event = System::timer_event + 1;

#ifndef __EMSCRIPTEN__
// Thread bouncers
static int system_timer_thread(void *ptr) {
	// Bounce back in to the class.
	System *sys = (System *)ptr;
	return sys->timer_thread();
}

static int system_loop_thread(void *ptr) {
	// Bounce back in to the class.
	System *sys = (System *)ptr;
	return sys->update_thread();
}
#endif

System::System() {
	m_input = SDL_CreateMutex();
	s_timer_stop = SDL_CreateSemaphore(0);
	s_loop_update = SDL_CreateSemaphore(0);
	s_loop_redraw = SDL_CreateSemaphore(0);
	s_loop_ended = SDL_CreateSemaphore(0);
}

System::~System() {
	SDL_DestroyMutex(m_input);
	SDL_DestroySemaphore(s_timer_stop);
	SDL_DestroySemaphore(s_loop_update);
	SDL_DestroySemaphore(s_loop_redraw);
	SDL_DestroySemaphore(s_loop_ended);
}

void System::run() {
	running = true;

	start = std::chrono::steady_clock::now();

	blit::update = ::update;
	blit::render = ::render;

	setup_base_path();

	blit::set_screen_mode(blit::lores);

#ifdef __EMSCRIPTEN__
	::init();
#else
	t_system_loop = SDL_CreateThread(system_loop_thread, "Loop", (void *)this);
	t_system_timer = SDL_CreateThread(system_timer_thread, "Timer", (void *)this);
#endif
}

int System::timer_thread() {
	// Signal the system loop every 10 msec.
	int dropped = 0;
	SDL_Event event = {};
	event.type = timer_event;

	while (SDL_SemWaitTimeout(s_timer_stop, 10)) {
		if (SDL_SemValue(s_loop_update)) {
			dropped++;
			if(dropped > 100) {
				dropped = 100;
				event.user.code = 2;
				SDL_PushEvent(&event);
			} else {
				event.user.code = 1;
				SDL_PushEvent(&event);
			}
		} else {
			SDL_SemPost(s_loop_update);
			dropped = 0;
			event.user.code = 0;
			SDL_PushEvent(&event);
		}
	}
	return 0;
}

int System::update_thread() {
  // Run the blit user code once every time we are signalled.
  SDL_Event event = {};
  event.type = loop_event;

  ::init(); // Run init here because the user can make it hang.

  while (true) {
    SDL_SemWait(s_loop_update);
    if(!running) break;
    bool rendered = loop();
    if(!running) break;
    if(rendered) {
      // present on main thread if we need to
      SDL_PushEvent(&event);
      SDL_SemWait(s_loop_redraw);
    }
  }
  SDL_SemPost(s_loop_ended);
  return 0;
}

bool System::loop() {
  SDL_LockMutex(m_input);
  blit::buttons = shadow_buttons;
  blit::tilt.x = shadow_tilt[0];
  blit::tilt.y = shadow_tilt[1];
  blit::tilt.z = shadow_tilt[2];
  blit::tilt.normalize();

  blit::joystick.x = shadow_joystick[0];
  blit::joystick.y = shadow_joystick[1];
  SDL_UnlockMutex(m_input);

  bool rendered = false;

  // only render at 50Hz (main loop runs at 100Hz)
  // however, the emscripten loop (usually) runs at the display refresh rate
  auto time_now = ::now();
#ifndef __EMSCRIPTEN__
  if(time_now - last_render_time >= 20)
#endif
  {
    blit::render(time_now);
    last_render_time = time_now;

    if(_mode != requested_mode || cur_format != requested_format) {
      _mode = requested_mode;
      cur_format = requested_format;
    }

    rendered = true;
  }

  blit::tick(::now());
  blit_input->rumble_controllers(blit::vibration);

  blit_multiplayer->update();

  return rendered;
}

Uint32 System::mode() {
	return _mode;
}

Uint32 System::format() {
	return Uint32(cur_format);
}

void System::update_texture(SDL_Texture *texture) {
  bool is_lores = _mode == blit::ScreenMode::lores;

  SDL_Rect dest_rect{0, 0, is_lores ? width / 2 : width, is_lores ? height / 2 : height};
  auto stride = dest_rect.w * blit::pixel_format_stride[int(cur_format)];

  if(cur_format == blit::PixelFormat::P) {
    uint8_t col_fb[max_width * max_height * 3];

    auto in = framebuffer, out = col_fb;
    auto size = dest_rect.w * dest_rect.h;

    for(int i = 0; i < size; i++) {
      uint8_t index = *(in++);
      (*out++) = palette[index].r;
      (*out++) = palette[index].g;
      (*out++) = palette[index].b;
    }

    SDL_UpdateTexture(texture, &dest_rect, col_fb, stride * 3);
  } else
    SDL_UpdateTexture(texture, &dest_rect, framebuffer, stride);
}

void System::notify_redraw() {
	SDL_SemPost(s_loop_redraw);
}

void System::set_joystick(int axis, float value) {
	if (axis < 2) {
		SDL_LockMutex(m_input);
		shadow_joystick[axis] = value;
		SDL_UnlockMutex(m_input);
	}
}

void System::set_tilt(int axis, float value) {
	if (axis < 3) {
		SDL_LockMutex(m_input);
		shadow_tilt[axis] = value;
		SDL_UnlockMutex(m_input);
	}
}

void System::set_button(int button, bool state) {
	SDL_LockMutex(m_input);
	if (state) {
		shadow_buttons |= button;
	} else {
		shadow_buttons &= ~button;
	}
	SDL_UnlockMutex(m_input);
}

void System::stop() {
  int returnValue;
  running = false;

  // make sure the update thread is not waiting for a render to complete
  SDL_SemPost(s_loop_redraw);

  if(SDL_SemWaitTimeout(s_loop_ended, 500)) {
    std::cerr << "User code appears to have frozen. Detaching thread." << std::endl;
    SDL_DetachThread(t_system_loop);
  } else {
    SDL_WaitThread(t_system_loop, &returnValue);
  }

  SDL_SemPost(s_timer_stop);
  SDL_WaitThread(t_system_timer, &returnValue);
}
