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

  int Run() {
    fidl_report::InputReportsReaderSyncPtr reader;
    client_->GetInputReportsReader(reader.NewRequest());

    zx_status_t status;
    run_ = true;
    while (run_) {
      // Get the report.
      fidl_report::InputReportsReader_ReadInputReports_Result result;
      status = reader->ReadInputReports(&result);
      if (status != ZX_OK) {
        printf("GetReports FIDL call returned %s\n", zx_status_get_string(status));
        return 1;
      }
      if (result.is_err()) {
        printf("GetReports FIDL result returned %s\n", zx_status_get_string(result.err()));
        return 1;
      }

      for (auto& report : result.response().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) {
    fbl::unique_fd 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);
      return ZX_OK;
    }

    return ZX_ERR_NOT_FOUND;
  }

  uint32_t max_x_ = 0;
  uint32_t max_y_ = 0;
  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();
}
