// Copyright 2022 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#include <array>
#include <cstdint>
#include <cwchar>
#include <forward_list>
#include <memory>
#include <string_view>
#include <utility>

#define PW_LOG_LEVEL PW_LOG_LEVEL_DEBUG

#include "ansi.h"
#include "app_common/common.h"
#include "pw_assert/assert.h"
#include "pw_assert/check.h"
#include "pw_board_led/led.h"
#include "pw_color/color.h"
#include "pw_color/colors_endesga32.h"
#include "pw_color/colors_pico8.h"
#include "pw_coordinates/vec2.h"
#include "pw_coordinates/vec_int.h"
#include "pw_draw/draw.h"
#include "pw_draw/font_set.h"
#include "pw_draw/pigweed_farm.h"
#include "pw_framebuffer/rgb565.h"
#include "pw_log/log.h"
#include "pw_ring_buffer/prefixed_entry_ring_buffer.h"
#include "pw_spin_delay/delay.h"
#include "pw_string/string_builder.h"
#include "pw_sys_io/sys_io.h"
#include "pw_touchscreen/touchscreen.h"
#include "text_buffer.h"

#if defined(USE_FREERTOS)
#include "FreeRTOS.h"
#include "task.h"
#endif  // if defined(USE_FREERTOS)

using pw::color::color_rgb565_t;
using pw::color::colors_pico8_rgb565;
using pw::coordinates::Size;
using pw::coordinates::Vector2;
using pw::display::Display;
using pw::draw::FontSet;
using pw::framebuffer::FramebufferRgb565;
using pw::ring_buffer::PrefixedEntryRingBuffer;

// TODO(cmumford): move this code into a pre_init section (i.e. boot.cc) which
//                 is part of the target. Not all targets currently have this.
#if defined(DEFINE_FREERTOS_MEMORY_FUNCTIONS)
std::array<StackType_t, 100 /*configMINIMAL_STACK_SIZE*/> freertos_idle_stack;
StaticTask_t freertos_idle_tcb;

std::array<StackType_t, configTIMER_TASK_STACK_DEPTH> freertos_timer_stack;
StaticTask_t freertos_timer_tcb;

extern "C" {
// Required for configUSE_TIMERS.
void vApplicationGetTimerTaskMemory(StaticTask_t** ppxTimerTaskTCBBuffer,
                                    StackType_t** ppxTimerTaskStackBuffer,
                                    uint32_t* pulTimerTaskStackSize) {
  *ppxTimerTaskTCBBuffer = &freertos_timer_tcb;
  *ppxTimerTaskStackBuffer = freertos_timer_stack.data();
  *pulTimerTaskStackSize = freertos_timer_stack.size();
}

void vApplicationGetIdleTaskMemory(StaticTask_t** ppxIdleTaskTCBBuffer,
                                   StackType_t** ppxIdleTaskStackBuffer,
                                   uint32_t* pulIdleTaskStackSize) {
  *ppxIdleTaskTCBBuffer = &freertos_idle_tcb;
  *ppxIdleTaskStackBuffer = freertos_idle_stack.data();
  *pulIdleTaskStackSize = freertos_idle_stack.size();
}
}  // extern "C"
#endif  // defined(DEFINE_FREERTOS_MEMORY_FUNCTIONS)

namespace {

constexpr color_rgb565_t kBlack = 0U;
constexpr color_rgb565_t kWhite = 0xffff;

class DemoDecoder : public AnsiDecoder {
 public:
  DemoDecoder(TextBuffer& log_text_buffer)
      : log_text_buffer_(log_text_buffer) {}

 protected:
  void SetFgColor(uint8_t r, uint8_t g, uint8_t b) override {
    fg_color_ = pw::color::ColorRGBA(r, g, b).ToRgb565();
  }
  void SetBgColor(uint8_t r, uint8_t g, uint8_t b) override {
    bg_color_ = pw::color::ColorRGBA(r, g, b).ToRgb565();
  }
  void EmitChar(char c) override {
    log_text_buffer_.DrawCharacter(TextBuffer::Char{c, fg_color_, bg_color_});
  }

 private:
  color_rgb565_t fg_color_ = kWhite;
  color_rgb565_t bg_color_ = kBlack;
  TextBuffer& log_text_buffer_;
};

// A simple implementation of a UI button.
class Button {
 public:
  // The label ptr must be valid throughout the lifetime of this object.
  Button(const wchar_t* label, const Vector2<int>& tl, const Size<int>& size)
      : label_(label), tl_(tl), size_(size) {}

  bool Contains(Vector2<int> pt) const {
    return pt.x >= tl_.x && pt.x < (tl_.x + size_.width) && pt.y >= tl_.y &&
           pt.y < (tl_.y + size_.height);
  }
  const wchar_t* label_;
  const Vector2<int> tl_;
  const Size<int> size_;
};

constexpr const wchar_t* kButtonLabel = L"Click to add logs";
constexpr int kButtonWidth = 108;
constexpr Vector2<int> kButtonTL = {320 - kButtonWidth, 0};
constexpr Size<int> kButtonSize = {kButtonWidth, 12};

TextBuffer s_log_text_buffer;
DemoDecoder s_demo_decoder(s_log_text_buffer);
Button g_button(kButtonLabel, kButtonTL, kButtonSize);
#if defined(USE_FREERTOS)
std::array<StackType_t, configMINIMAL_STACK_SIZE> s_freertos_stack;
StaticTask_t s_freertos_tcb;
#endif  // defined(USE_FREERTOS)

void DrawButton(const Button& button,
                color_rgb565_t bg_color,
                FramebufferRgb565& framebuffer) {
  pw::draw::DrawRectWH(&framebuffer,
                       button.tl_.x,
                       button.tl_.y,
                       button.size_.width,
                       button.size_.height,
                       bg_color,
                       /*filled=*/true);
  constexpr int kMargin = 2;
  Vector2<int> tl{button.tl_.x + kMargin, button.tl_.y + kMargin};
  DrawString(
      button.label_, tl, kBlack, bg_color, pw::draw::font6x8, framebuffer);
}

// Draw a font sheet starting at the given top-left screen coordinates.
Vector2<int> DrawTestFontSheet(Vector2<int> tl,
                               int num_columns,
                               color_rgb565_t fg_color,
                               color_rgb565_t bg_color,
                               const FontSet& font,
                               FramebufferRgb565& framebuffer) {
  Vector2<int> max_extents = tl;
  const int initial_x = tl.x;
  for (int c = font.starting_character; c <= font.ending_character; c++) {
    int char_idx = c - font.starting_character;
    if (char_idx % num_columns == 0) {
      tl.x = initial_x;
      tl.y += font.height;
    }
    auto char_size =
        DrawCharacter(c, tl, fg_color, bg_color, font, framebuffer);
    tl.x += char_size.width;
    max_extents.x = std::max(tl.x, max_extents.x);
    max_extents.y = std::max(tl.y, max_extents.y);
  }
  max_extents.y += font.height;
  return max_extents;
}

Vector2<int> DrawColorFontSheet(Vector2<int> tl,
                                int num_columns,
                                color_rgb565_t fg_color,
                                const FontSet& font,
                                FramebufferRgb565& framebuffer) {
  constexpr int kNumColors = sizeof(pw::color::colors_endesga32_rgb565) /
                             sizeof(pw::color::colors_endesga32_rgb565[0]);
  const int initial_x = tl.x;
  Vector2<int> max_extents = tl;
  for (int c = font.starting_character; c <= font.ending_character; c++) {
    int char_idx = c - font.starting_character;
    if (char_idx % num_columns == 0) {
      tl.x = initial_x;
      tl.y += font.height;
    }
    auto char_size =
        DrawCharacter(c,
                      tl,
                      fg_color,
                      pw::color::colors_endesga32_rgb565[char_idx % kNumColors],
                      font,
                      framebuffer);
    tl.x += char_size.width;
    max_extents.x = std::max(tl.x, max_extents.x);
    max_extents.y = std::max(tl.y, max_extents.y);
  }
  max_extents.y += font.height;
  return max_extents;
}

// The logging callback used to capture log messages sent to pw_log.
void LogCallback(std::string_view log) {
  for (auto c : log) {
    s_demo_decoder.ProcessChar(c);
  }
  s_demo_decoder.ProcessChar('\n');

  pw::sys_io::WriteLine(log).IgnoreError();
};

// Draw the Pigweed sprite and artwork at the top of the display.
// Returns the bottom Y coordinate drawn.
int DrawPigweedSprite(FramebufferRgb565& framebuffer) {
  int sprite_pos_x = 10;
  int sprite_pos_y = 24;
  int sprite_scale = 4;
  int border_size = 8;

  // Draw the dark blue border
  pw::draw::DrawRectWH(
      &framebuffer,
      sprite_pos_x - border_size,
      sprite_pos_y - border_size,
      pigweed_farm_sprite_sheet.width * sprite_scale + (border_size * 2),
      pigweed_farm_sprite_sheet.height * sprite_scale + (border_size * 2),
      colors_pico8_rgb565[COLOR_DARK_BLUE],
      true);

  // Shrink the border
  border_size = 4;

  // Draw the light blue background
  pw::draw::DrawRectWH(
      &framebuffer,
      sprite_pos_x - border_size,
      sprite_pos_y - border_size,
      pigweed_farm_sprite_sheet.width * sprite_scale + (border_size * 2),
      pigweed_farm_sprite_sheet.height * sprite_scale + (border_size * 2),
      colors_pico8_rgb565[COLOR_BLUE],
      true);

  static Vector2<int> sun_offset;
  static int motion_dir = -1;
  static int frame_num = 0;
  frame_num++;
  if ((frame_num % 5) == 0)
    sun_offset.x += motion_dir;
  if ((frame_num % 15) == 0)
    sun_offset.y -= motion_dir;
  if (sun_offset.x < -60)
    motion_dir = 1;
  else if (sun_offset.x > 10)
    motion_dir = -1;

  // Draw the Sun
  pw::draw::DrawCircle(&framebuffer,
                       sun_offset.x + sprite_pos_x +
                           (pigweed_farm_sprite_sheet.width * sprite_scale) -
                           32,
                       sun_offset.y + sprite_pos_y,
                       20,
                       colors_pico8_rgb565[COLOR_ORANGE],
                       true);
  pw::draw::DrawCircle(&framebuffer,
                       sun_offset.x + sprite_pos_x +
                           (pigweed_farm_sprite_sheet.width * sprite_scale) -
                           32,
                       sun_offset.y + sprite_pos_y,
                       18,
                       colors_pico8_rgb565[COLOR_YELLOW],
                       true);

  // Draw the farm sprite's shadow
  pigweed_farm_sprite_sheet.current_index = 1;
  pw::draw::DrawSprite(&framebuffer,
                       sprite_pos_x + 2,
                       sprite_pos_y + 2,
                       &pigweed_farm_sprite_sheet,
                       4);

  // Draw the farm sprite
  pigweed_farm_sprite_sheet.current_index = 0;
  pw::draw::DrawSprite(
      &framebuffer, sprite_pos_x, sprite_pos_y, &pigweed_farm_sprite_sheet, 4);

  return 76;
}

void DrawFPS(Vector2<int> tl,
             FramebufferRgb565& framebuffer,
             std::wstring_view fps_msg) {
  if (fps_msg.empty())
    return;

  DrawString(fps_msg,
             tl,
             colors_pico8_rgb565[COLOR_PEACH],
             kBlack,
             pw::draw::font6x8,
             framebuffer);
}

// Draw the pigweed text banner.
// Returns the bottom Y coordinate of the bottommost pixel set.
int DrawPigweedBanner(Vector2<int> tl, FramebufferRgb565& framebuffer) {
  constexpr std::array<std::wstring_view, 5> pigweed_banner = {
      L"▒█████▄   █▓  ▄███▒  ▒█    ▒█ ░▓████▒ ░▓████▒ ▒▓████▄",
      L" ▒█░  █░ ░█▒ ██▒ ▀█▒ ▒█░ █ ▒█  ▒█   ▀  ▒█   ▀  ▒█  ▀█▌",
      L" ▒█▄▄▄█░ ░█▒ █▓░ ▄▄░ ▒█░ █ ▒█  ▒███    ▒███    ░█   █▌",
      L" ▒█▀     ░█░ ▓█   █▓ ░█░ █ ▒█  ▒█   ▄  ▒█   ▄  ░█  ▄█▌",
      L" ▒█      ░█░ ░▓███▀   ▒█▓▀▓█░ ░▓████▒ ░▓████▒ ▒▓████▀"};

  // Draw the Pigweed "ASCII" banner.
  for (auto text_row : pigweed_banner) {
    Size<int> string_dims = DrawString(text_row,
                                       tl,
                                       colors_pico8_rgb565[COLOR_PINK],
                                       kBlack,
                                       pw::draw::font6x8_box_chars,
                                       framebuffer);
    tl.y += string_dims.height;
  }
  return tl.y - pw::draw::font6x8_box_chars.height;
}

// Draw the font sheets.
// Returns the bottom Y coordinate drawn.
int DrawFontSheets(Vector2<int> tl, FramebufferRgb565& framebuffer) {
  constexpr int kFontSheetVerticalPadding = 4;
  constexpr int kFontSheetNumColumns = 48;

  int initial_x = tl.x;
  tl = DrawColorFontSheet(tl,
                          kFontSheetNumColumns,
                          /*fg_color=*/kBlack,
                          pw::draw::font6x8,
                          framebuffer);

  tl.x = initial_x;
  tl.y -= pw::draw::font6x8.height;
  tl.y += kFontSheetVerticalPadding;

  tl = DrawTestFontSheet(tl,
                         kFontSheetNumColumns,
                         /*fg_color=*/kWhite,
                         /*bg_color=*/kBlack,
                         pw::draw::font6x8,
                         framebuffer);

  tl.x = initial_x;
  tl.y += kFontSheetVerticalPadding;

  Size<int> string_dims = DrawString(L"Box Characters:",
                                     tl,
                                     /*fg_color=*/kWhite,
                                     /*bg_color=*/kBlack,
                                     pw::draw::font6x8,
                                     framebuffer);
  tl.x += string_dims.width + pw::draw::font6x8.width;
  tl.y -= pw::draw::font6x8.height;

  tl = DrawTestFontSheet(tl,
                         /*num_columns=*/32,
                         /*fg_color=*/kWhite,
                         /*bg_color=*/kBlack,
                         pw::draw::font6x8_box_chars,
                         framebuffer);
  return tl.y;
}

// Draw the application header section which is mostly static text/graphics.
// Return the height (in pixels) of the header.
int DrawHeader(FramebufferRgb565& framebuffer, std::wstring_view fps_msg) {
  DrawButton(
      g_button, /*bg_color=*/colors_pico8_rgb565[COLOR_BLUE], framebuffer);
  Vector2<int> tl = {0, 0};
  tl.y = DrawPigweedSprite(framebuffer);

  tl.y = DrawPigweedBanner(tl, framebuffer);
  constexpr int kFontSheetMargin = 4;
  tl.y += kFontSheetMargin;

  DrawFPS({1, 2}, framebuffer, fps_msg);

  return DrawFontSheets(tl, framebuffer);
}

void DrawLogTextBuffer(int top,
                       const FontSet& font,
                       FramebufferRgb565& framebuffer) {
  constexpr int kLeft = 0;
  Vector2<int> loc;
  Vector2<int> pos{kLeft, top};
  Size<int> buffer_size = s_log_text_buffer.GetSize();
  for (loc.y = 0; loc.y < buffer_size.height; loc.y++) {
    for (loc.x = 0; loc.x < buffer_size.width; loc.x++) {
      auto ch = s_log_text_buffer.GetChar(loc);
      if (!ch.ok())
        continue;
      Size<int> char_size = DrawCharacter(ch->ch,
                                          pos,
                                          ch->foreground_color,
                                          ch->background_color,
                                          font,
                                          framebuffer);
      pos.x += char_size.width;
    }
    pos.y += font.height;
    pos.x = kLeft;
  }
}

void DrawFrame(FramebufferRgb565& framebuffer, std::wstring_view fps_msg) {
  constexpr int kHeaderMargin = 4;
  int header_bottom = DrawHeader(framebuffer, fps_msg);
  DrawLogTextBuffer(
      header_bottom + kHeaderMargin, pw::draw::font6x8, framebuffer);
}

void CreateDemoLogMessages() {
  PW_LOG_CRITICAL("An irrecoverable error has occurred!");
  PW_LOG_ERROR("There was an error on our last operation");
  PW_LOG_WARN("Looks like something is amiss; consider investigating");
  PW_LOG_INFO("The operation went as expected");
  PW_LOG_DEBUG("Debug output");
}

// Given a ring buffer full of uint32_t values, return the average value
// or zero if empty.
uint32_t CalcAverageUint32Value(PrefixedEntryRingBuffer& ring_buffer) {
  if (!ring_buffer.EntryCount())
    return 0;
  uint64_t sum = 0;
  uint32_t count = 0;
  pw::ring_buffer::PrefixedEntryRingBufferMulti::iterator it =
      ring_buffer.begin();
  for (; it != ring_buffer.end(); ++it) {
    PW_ASSERT(it->buffer.size() == sizeof(uint32_t));
    uint32_t val;
    std::memcpy(&val, it->buffer.data(), sizeof(val));
    sum += val;
    count++;
  }
  return sum / count;
}

}  // namespace

void MainTask(void* pvParameters) {
  // Timing variables
  uint32_t frame_start_millis = pw::spin_delay::Millis();
  uint32_t frames = 0;
  int frames_per_second = 0;
  std::array<wchar_t, 40> fps_buffer = {0};
  std::wstring_view fps_view(fps_buffer.data(), 0);
  std::byte draw_buffer[30 * sizeof(uint32_t)];
  std::byte flush_buffer[30 * sizeof(uint32_t)];
  PrefixedEntryRingBuffer draw_times;
  PrefixedEntryRingBuffer flush_times;

  draw_times.SetBuffer(draw_buffer);
  flush_times.SetBuffer(flush_buffer);

  pw::log_basic::SetOutput(LogCallback);

  pw::board_led::Init();
  PW_CHECK_OK(Common::Init());

  Display& display = Common::GetDisplay();
  FramebufferRgb565 framebuffer = display.GetFramebuffer();
  PW_ASSERT(framebuffer.IsValid());

  pw::draw::Fill(&framebuffer, kBlack);

  PW_LOG_INFO("pw::touchscreen::Init()");
  pw::touchscreen::Init();

  pw::coordinates::Vec3Int last_frame_touch_state(0, 0, 0);

  DrawFrame(framebuffer, fps_view);
  // Push the frame buffer to the screen.
  display.ReleaseFramebuffer(std::move(framebuffer));

  // The display loop.
  while (1) {
    pw::coordinates::Vec3Int point = display.GetTouchPoint();
    // Check for touchscreen events.
    if (display.TouchscreenAvailable() && display.NewTouchEvent()) {
      if (point.z > 0) {
        bool button_just_pressed = false;
        if (point.z != last_frame_touch_state.z)
          button_just_pressed = true;
        // New touch event
        Vector2<int> touch_location{point.x, point.y};

        PW_LOG_DEBUG("Touch: x:%d, y:%d, z:%d", point.x, point.y, point.z);

        // If a button was just pressed, call CreateDemoLogMessages.
        if (button_just_pressed && g_button.Contains(touch_location)) {
          CreateDemoLogMessages();
        }
      }
    }
    last_frame_touch_state.x = point.x;
    last_frame_touch_state.y = point.y;
    last_frame_touch_state.z = point.z;

    uint32_t start = pw::spin_delay::Millis();
    framebuffer = display.GetFramebuffer();
    if (!framebuffer.IsValid())
      continue;
    pw::draw::Fill(&framebuffer, kBlack);
    DrawFrame(framebuffer, fps_view);
    uint32_t end = pw::spin_delay::Millis();
    uint32_t time = end - start;
    draw_times.PushBack(pw::as_bytes(pw::span{std::addressof(time), 1}));
    start = end;

    display.ReleaseFramebuffer(std::move(framebuffer));
    time = pw::spin_delay::Millis() - start;
    flush_times.PushBack(pw::as_bytes(pw::span{std::addressof(time), 1}));

    // Every second make a log message.
    frames++;
    if (pw::spin_delay::Millis() > frame_start_millis + 1000) {
      frames_per_second = frames;
      frames = 0;
      PW_LOG_INFO("Time: %lu - FPS: %d",
                  static_cast<unsigned long>(pw::spin_delay::Millis()),
                  frames_per_second);
      int len = std::swprintf(fps_buffer.data(),
                              fps_buffer.size(),
                              L"FPS:%d, Draw:%dms, Flush:%dms",
                              frames_per_second,
                              CalcAverageUint32Value(draw_times),
                              CalcAverageUint32Value(flush_times));
      fps_view = std::wstring_view(fps_buffer.data(), len);

      frame_start_millis = pw::spin_delay::Millis();
    }
  }
}

int main(void) {
#if defined(USE_FREERTOS)
  TaskHandle_t task_handle = xTaskCreateStatic(MainTask,
                                               "main",
                                               s_freertos_stack.size(),
                                               /*pvParameters=*/nullptr,
                                               tskIDLE_PRIORITY,
                                               s_freertos_stack.data(),
                                               &s_freertos_tcb);
  PW_CHECK_NOTNULL(task_handle);  // Ensure it succeeded.
  vTaskStartScheduler();
#else
  MainTask(/*pvParameters=*/nullptr);
#endif
  return 0;
}
