// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <assert.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <fuchsia/input/report/cpp/fidl.h>
#include <lib/fdio/fdio.h>
#include <lib/fdio/unsafe.h>
#include <lib/framebuffer/framebuffer.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <zircon/process.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>

#include <ddk/device.h>

#include "src/lib/files/unique_fd.h"

namespace simple_touch {

namespace fidl_report = ::fuchsia::input::report;

typedef struct display_info {
  uint32_t width;
  uint32_t height;
  uint32_t stride;
  zx_pixel_format_t format;
} display_info_t;

// This class manages the framebuffer. It will initialize the buffer, draw to it,
// and flush it back to memory.
// At the moment we only support a single buffer with a pixel size of 32 byes and
// a color format of RGBA.
class FrameBuffer {
 public:
  ~FrameBuffer();
  zx_status_t Init();
  // Draw a square point centered at |x| and |y| with |width| and |height|.
  void DrawPoint(uint32_t color, uint32_t x, uint32_t y, uint8_t width, uint8_t height);
  void FlushScreen() { zx_cache_flush(pixels_, pixels_size_, ZX_CACHE_FLUSH_DATA); }
  void ClearScreen();
  display_info_t DisplayInfo() { return display_info_; }

 private:
  display_info_t display_info_ = {};
  uint32_t* pixels_ = nullptr;
  size_t pixels_size_ = 0;
};

FrameBuffer::~FrameBuffer() {
  if (pixels_) {
    _zx_vmar_unmap(zx_vmar_root_self(), reinterpret_cast<zx_vaddr_t>(pixels_), pixels_size_);
  }
  fb_release();
}

zx_status_t FrameBuffer::Init() {
  const char* err;
  zx_status_t status = fb_bind(true, &err);
  if (status != ZX_OK) {
    printf("failed to open framebuffer: %d (%s)\n", status, err);
    return status;
  }
  display_info_t info;
  fb_get_config(&info.width, &info.height, &info.stride, &info.format);

  zx_handle_t vmo = fb_get_single_buffer();

  printf("format = %d\n", info.format);
  printf("width = %d\n", info.width);
  printf("height = %d\n", info.height);
  printf("stride = %d\n", info.stride);

  pixels_size_ = info.stride * ZX_PIXEL_FORMAT_BYTES(info.format) * info.height;
  uintptr_t frame_buffer_ptr;
  status = zx_vmar_map(zx_vmar_root_self(), ZX_VM_PERM_READ | ZX_VM_PERM_WRITE, 0, vmo, 0,
                       pixels_size_, &frame_buffer_ptr);
  if (status != ZX_OK) {
    return status;
  }

  pixels_ = (uint32_t*)frame_buffer_ptr;
  display_info_ = info;

  ClearScreen();
  FlushScreen();
  return ZX_OK;
}

void FrameBuffer::DrawPoint(uint32_t color, uint32_t x, uint32_t y, uint8_t width, uint8_t height) {
  uint32_t fb_width = display_info_.stride;
  uint32_t fb_height = display_info_.height;
  uint32_t xrad = (width + 1) / 2;
  uint32_t yrad = (height + 1) / 2;

  uint32_t xmin = (xrad > x) ? 0 : x - xrad;
  uint32_t xmax = (xrad > fb_width - x) ? fb_width : x + xrad;
  uint32_t ymin = (yrad > y) ? 0 : y - yrad;
  uint32_t ymax = (yrad > fb_height - y) ? fb_height : y + yrad;

  for (uint32_t px = xmin; px < xmax; px++) {
    for (uint32_t py = ymin; py < ymax; py++) {
      *(pixels_ + py * fb_width + px) = color;
    }
  }
}

void FrameBuffer::ClearScreen() { memset(pixels_, 0xff, pixels_size_); }

// This class sits over the framebuffer and is responsible for associating touches with color,
// for drawing the clear and exit button, and for recognizing button touches.
class TouchApp {
 public:
  zx_status_t Init() {
    zx_status_t status = frame_buffer_.Init();
    if (status != ZX_OK) {
      return status;
    }
    display_info_ = frame_buffer_.DisplayInfo();

    ClearScreen();
    FlushScreen();

    status = GetTouchScreen();
    if (status != ZX_OK) {
      return status;
    }

    return ZX_OK;
  }

  void ClearScreen() {
    frame_buffer_.ClearScreen();
    frame_buffer_.DrawPoint(0xff00ff, display_info_.stride - (kButtonSize / 2), (kButtonSize / 2),
                            kButtonSize, kButtonSize);
    frame_buffer_.DrawPoint(0x0000ff, (kButtonSize / 2), display_info_.height - (kButtonSize / 2),
                            kButtonSize, kButtonSize);
  }

  void FlushScreen() { frame_buffer_.FlushScreen(); }

  void DrawPoint(uint32_t color, uint32_t x, uint32_t y, uint8_t width, uint8_t height) {
    x = x * display_info_.width / max_x_;
    y = y * display_info_.height / max_y_;
    frame_buffer_.DrawPoint(color, x, y, width, height);

    if (x + kButtonSize > display_info_.width && y < kButtonSize) {
      ClearScreen();
      FlushScreen();
    }
    if (((y + kButtonSize) > display_info_.height) && (x < kButtonSize)) {
      run_ = false;
    }
  }

  void SetMaxValues(uint32_t x, uint32_t y) {
    max_x_ = x;
    max_y_ = y;
  }

  std::vector<fidl_report::InputReport> reports;
  int Run() {
    zx_status_t status;
    run_ = true;
    while (run_) {
      // Wait on the event to be readable.
      status = has_reports_event_.wait_one(DEV_STATE_READABLE, zx::time::infinite(), nullptr);
      if (status != ZX_OK) {
        return 1;
      }

      // Get the report.
      status = client_->GetReports(&reports);
      if (status != ZX_OK) {
        printf("GetReports FIDL call returned %s\n", zx_status_get_string(status));
        return 1;
      }

      for (auto& report : reports) {
        if (!report.has_touch()) {
          continue;
        }
        if (!report.touch().has_contacts()) {
          continue;
        }
        for (size_t i = 0; i < report.touch().contacts().size(); i++) {
          uint32_t x = report.touch().contacts()[i].position_x();
          uint32_t y = report.touch().contacts()[i].position_y();
          uint32_t contact_id = report.touch().contacts()[i].contact_id();
          uint32_t width = 10;
          uint32_t height = 10;
          DrawPoint(kColors[contact_id % kColors.size()], x, y, width, height);
        }
      }
      FlushScreen();
    }
    return 0;
  }

 private:
  static constexpr uint32_t kButtonSize = 50;
  // Array of colors for each finger
  static constexpr std::array<uint32_t, 10> kColors = {
      0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffff00, 0x00ff00ff,
      0x0000ffff, 0x00000000, 0x00f0f0f0, 0x00f00f00, 0x000ff000,
  };

  // Gets the touch client from a file path. Sets |client_| on success.
  zx_status_t GetClientFromFilePath(const char* path) {
    fxl::UniqueFD fd(open(path, O_RDWR));
    if (!fd.is_valid()) {
      return ZX_ERR_INTERNAL;
    }

    zx::channel chan;
    zx_status_t status = fdio_get_service_handle(fd.release(), chan.reset_and_get_address());
    if (status != ZX_OK) {
      printf("Ftdio get handle failed with %s\n", zx_status_get_string(status));
      return status;
    }
    client_.Bind(std::move(chan));
    return ZX_OK;
  }

  bool IsTouchscreen(const fidl_report::DeviceDescriptor& descriptor) {
    if (!descriptor.has_touch() || !descriptor.touch().has_input()) {
      return false;
    }
    const fidl_report::TouchInputDescriptor& touch_desc = descriptor.touch().input();
    if (!touch_desc.has_touch_type() ||
        (touch_desc.touch_type() != fidl_report::TouchType::TOUCHSCREEN)) {
      return false;
    }
    return true;
  }

  // Iterates through the input-report directory and finds a touchscreen.
  // Gets that touchscreen's client and report event.
  zx_status_t GetTouchScreen() {
    // Find the touchscreen.
    struct dirent* de;
    DIR* dir = opendir("/dev/class/input-report");
    if (!dir) {
      printf("failed to open %s: %d\n", "/dev/class/input-report", errno);
      return ZX_ERR_INTERNAL;
    }

    while ((de = readdir(dir)) != NULL) {
      char devname[128];

      if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) {
        continue;
      }

      // Get the |client_| from the path.
      snprintf(devname, sizeof(devname), "%s/%s", "/dev/class/input-report", de->d_name);
      zx_status_t status = GetClientFromFilePath(devname);

      // Get the DeviceDescriptor.
      fidl_report::DeviceDescriptor device_descriptor;
      status = client_->GetDescriptor(&device_descriptor);
      if (status != ZX_OK) {
        printf("GetDescriptor FIDL call returned %s\n", zx_status_get_string(status));
        return status;
      }

      if (!IsTouchscreen(device_descriptor)) {
        continue;
      }

      SetMaxValues(device_descriptor.touch().input().contacts()[0].position_x().range.max,
                   device_descriptor.touch().input().contacts()[0].position_y().range.max);

      printf("Found touchscreen at %s\n", devname);

      // Get the reports event.
      zx_status_t wire_status = client_->GetReportsEvent(&status, &has_reports_event_);
      if (wire_status != ZX_OK) {
        printf("GetReportsEvent FIDL call returned %s\n", zx_status_get_string(wire_status));
        return 1;
      }
      if (status != ZX_OK) {
        printf("GetReportsEvent FIDL call returned %s\n", zx_status_get_string(status));
        return 1;
      }
      return ZX_OK;
    }

    return ZX_ERR_NOT_FOUND;
  }

  uint32_t max_x_ = 0;
  uint32_t max_y_ = 0;
  zx::event has_reports_event_;
  fidl_report::InputDeviceSyncPtr client_;
  FrameBuffer frame_buffer_;
  display_info_t display_info_ = {};
  bool run_ = true;
};

}  // namespace simple_touch

int main(int argc, char* argv[]) {
  simple_touch::TouchApp app;
  zx_status_t status = app.Init();
  if (status != ZX_OK) {
    return 1;
  }

  return app.Run();
}
