// Copyright 2018 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 "runner.h"

#include <fbl/algorithm.h>
#include <fcntl.h>
#include <zircon/device/display-controller.h>
#include <cmath>

namespace display_test {
namespace internal {

constexpr const char* kDisplayController = "/dev/class/display-controller/000";
constexpr const char* kCameraDir = "/dev/class/camera";

constexpr uint32_t kDisplayRate = 60;
constexpr uint32_t kDisplayFormat = ZX_PIXEL_FORMAT_ARGB_8888;

bool is_opaque(uint32_t val) { return (val & 0xff000000) == 0xff000000; }

// Src is always premultipled
uint32_t multiply_component(uint32_t dest, uint32_t src, uint8_t offset) {
  uint32_t alpha_comp = src >> 24;
  uint32_t dest_val =
      ((((dest >> offset) & 0xff) * (255 - alpha_comp)) + 254) / 255;
  uint32_t ret = dest_val + ((src >> offset) & 0xff);
  if (ret > 255) {
    ret = 255;
  }
  return ret << offset;
}

uint32_t multiply(uint32_t dest, uint32_t src) {
  if (is_opaque(src)) {
    return src;
  }

  return 0xff000000 | multiply_component(dest, src, 16) |
         multiply_component(dest, src, 8) | multiply_component(dest, src, 0);
}

uint8_t clip(float in) {
  return in < 0 ? 0 : (in > 255 ? 255 : static_cast<uint8_t>(in + .5));
}

// Takes 4 bytes of YUY2 and writes 8 bytes of RGBA
// TODO(stevensd): RGBA -> YUY2 might be more reliable/efficient
void yuy2_to_bgra(uint8_t* yuy2, uint32_t* argb1, uint32_t* argb2) {
  uint8_t* bgra1 = reinterpret_cast<uint8_t*>(argb1);
  uint8_t* bgra2 = reinterpret_cast<uint8_t*>(argb2);
  int u = yuy2[1] - 128;
  int y1 = yuy2[0];
  int v = yuy2[3] - 128;
  int y2 = yuy2[2];

  bgra1[0] = clip(y1 + 1.772 * u);
  bgra1[1] = clip(y1 - .344 * u - .714 * v);
  bgra1[2] = clip(y1 + 1.402 * v);
  bgra1[3] = 0xff;

  bgra2[0] = clip(y2 + 1.772 * u);
  bgra2[1] = clip(y2 - .344 * u - .714 * v);
  bgra2[2] = clip(y2 + 1.402 * v);
  bgra2[3] = 0xff;
}

static bool compare_component(uint32_t argb1, uint32_t argb2, uint32_t offset) {
  uint8_t comp1 = (argb1 >> (offset * 8)) & 0xff;
  uint8_t comp2 = (argb2 >> (offset * 8)) & 0xff;
  uint8_t diff = comp1 - comp2;
  // Unfortunately this is *very* permissive, since it's there are a lot of
  // places where slight rounding/implementation differences can accumulate
  // (i.e. the display controller blending, rgb->yuv, yuv->rgb, our blending).
  return static_cast<uint8_t>(diff + 6) < 13;
}

static bool compare_colors(uint32_t argb1, uint32_t argb2) {
  return compare_component(argb1, argb2, 0) &&
         compare_component(argb1, argb2, 1) &&
         compare_component(argb1, argb2, 2);
}

Runner::Runner(async::Loop* loop) : loop_(loop), runner_context_(this) {}

zx_pixel_format_t Runner::format() const { return kDisplayFormat; }

zx_status_t Runner::Start(const char* display_name) {
  zx_status_t status;

  display_name_ = display_name;

  camera_watcher_ = fsl::DeviceWatcher::Create(
      kCameraDir, fit::bind_member(this, &Runner::OnCameraAvailable));
  camera_stream_.events().OnFrameAvailable =
      fit::bind_member(this, &Runner::FrameNotifyCallback);

  status = loop_->Run();
  if (!display_id_ || !camera_setup_ || !display_ownership_) {
    status = ZX_ERR_INTERNAL;
  } else if (status == ZX_ERR_CANCELED) {
    status = ZX_OK;
  }
  return status;
}

void Runner::OnCameraAvailable(int dir_fd, std::string filename) {
  fxl::UniqueFD fd(openat(dir_fd, filename.c_str(), O_RDWR));
  if (!fd.is_valid()) {
    printf("Failed to open camera %s\n", filename.c_str());
    return;
  }

  zx::channel channel;
  ssize_t res =
      ioctl_camera_get_channel(fd.get(), channel.reset_and_get_address());
  if (res < 0) {
    printf("Failed to obtain channel for camera %s\n", filename.c_str());
    return;
  }

  camera_control_.Bind(std::move(channel), loop_->dispatcher());

  camera_control_->GetFormats(
      0, fit::bind_member(this, &Runner::GetFormatCallback));
}

void Runner::GetFormatCallback(
    ::fidl::VectorPtr<fuchsia::camera::VideoFormat> fmts, uint32_t total_count,
    zx_status_t status) {
  uint32_t idx;
  for (idx = 0; idx < fmts->size(); idx++) {
    auto& format = fmts.get()[idx];
    uint32_t capture_fps = round(1.0 * format.rate.frames_per_sec_numerator /
                                 format.rate.frames_per_sec_denominator);
    if (capture_fps != kDisplayRate) {
      continue;
    }

    if (format.format.pixel_format.type ==
        fuchsia::sysmem::PixelFormatType::YUY2) {
      break;
    }

    ZX_ASSERT(format.format.width % 2 == 0);
  }

  if (idx >= fmts->size()) {
    // Technically we should call GetFormat again, but we can handle that
    // when it comes it, since this is just a test program.
    printf("Failed to find matching capture format\n");
    return;
  }

  // We found a camera, so stop watching the dir for new cameras.
  camera_watcher_.reset();

  auto& format = fmts.get()[idx];
  camera_stride_ = format.format.planes[0].bytes_per_row;
  width_ = format.format.width;
  height_ = format.format.height;

  fuchsia::sysmem::BufferCollectionInfo buffer_collection;
  size_t buffer_size = fbl::round_up(
      format.format.height * format.format.planes[0].bytes_per_row, 4096u);
  buffer_collection.buffer_count = kMaxFrames;
  buffer_collection.vmo_size = buffer_size;
  // TODO(FIDL-204/kulakowski) Make this a union again when C bindings
  // are rationalized.
  buffer_collection.format.image = std::move(format.format);

  for (uint32_t i = 0; i < kMaxFrames; ++i) {
    zx::vmo vmo;

    status = zx::vmo::create(buffer_size, 0, &vmo);
    ZX_ASSERT(status == ZX_OK);

    status = zx::vmar::root_self()->map(
        0, vmo, 0, buffer_size, ZX_VM_FLAG_PERM_READ | ZX_VM_FLAG_PERM_WRITE,
        reinterpret_cast<zx_vaddr_t*>(camera_buffers_ + i));
    ZX_ASSERT(status == ZX_OK);

    buffer_collection.vmos[i] = std::move(vmo);
  }

  zx::eventpair driver_token;
  status = zx::eventpair::create(0, &stream_token_, &driver_token);
  ZX_ASSERT(status == ZX_OK);

  camera_control_->CreateStream(std::move(buffer_collection), format.rate,
                                camera_stream_.NewRequest(),
                                std::move(driver_token));

  camera_stream_->Start();
  camera_setup_ = true;

  InitDisplay();
}

void Runner::InitDisplay() {
  zx_status_t status;
  fxl::UniqueFD fd(open(kDisplayController, O_RDWR));
  if (!fd.is_valid()) {
    ZX_ASSERT_MSG(false, "Failed to open display controller");
  }

  zx::channel dc_handle;
  if (ioctl_display_controller_get_handle(
          fd.get(), dc_handle.reset_and_get_address()) != sizeof(zx_handle_t)) {
    ZX_ASSERT_MSG(false, "Failed to obtain display controller handle");
  }

  dc_fd_ = std::move(fd);
  if ((status = display_controller_.Bind(std::move(dc_handle),
                                         loop_->dispatcher())) != ZX_OK) {
    ZX_ASSERT_MSG(false, "Failed to bind to display controller %d\n", status);
  }
  display_controller_.events().DisplaysChanged =
      fit::bind_member(this, &Runner::OnDisplaysChanged);
  display_controller_.events().ClientOwnershipChange =
      fit::bind_member(this, &Runner::OnClientOwnershipChange);
  display_controller_.events().Vsync = fit::bind_member(this, &Runner::OnVsync);
  display_controller_.set_error_handler(
      [this]() { ZX_ASSERT_MSG(false, "Display controller failure"); });

  calibration_image_a_ = runner_context_.CreateImage(width_, height_);
  calibration_image_b_ = runner_context_.CreateImage(width_, height_);
  calibration_layer_ = runner_context_.CreatePrimaryLayer(width_, height_);
  runner_context_.SetLayers(std::vector<Layer*>({calibration_layer_}));
}

void Runner::OnDisplaysChanged(::fidl::VectorPtr<fuchsia::display::Info> added,
                               ::fidl::VectorPtr<uint64_t> removed) {
  ZX_ASSERT_MSG(!display_id_, "Display change while tests are running");
  for (auto& info : added.get()) {
    if (strcmp(info.monitor_name.get().c_str(), display_name_)) {
      continue;
    }
    for (auto& mode : info.modes.get()) {
      if (mode.horizontal_resolution != width_ ||
          mode.vertical_resolution != height_ ||
          mode.refresh_rate_e2 != kDisplayRate * 100) {
        continue;
      }
      display_id_ = info.id;
    }
  }
  ZX_ASSERT_MSG(display_id_, "Failed to find compatible display");

  display_controller_->EnableVsync(true);

  OnResourceReady();
}

void Runner::OnClientOwnershipChange(bool is_owner) {
  if (is_owner) {
    display_ownership_ = true;
    OnResourceReady();
  } else {
    ZX_ASSERT_MSG(false, "Lost display ownership");
  }
}

void Runner::OnShutdownCallback() { ZX_ASSERT_MSG(false, "Camera shutdown"); }

void Runner::OnResourceReady() {
  if (!display_id_ || !camera_setup_ || !display_ownership_) {
    return;
  }
  if (!runner_context_.IsReady()) {
    return;
  }

  if (!test_context_) {
    loop_->Quit();
    return;
  } else if (!test_context_->IsReady()) {
    return;
  }
  test_running_ = true;

  // We know the first 2 calibration frames are fine, so skip them
  CheckFrameConfig(2);
}

void Runner::Stop() { camera_stream_->Stop(); }

Context* Runner::StartTest() {
  test_context_ = std::unique_ptr<Context>(new Context(this));

  ZX_ASSERT_MSG(!test_running_, "Test starting while busy");
  test_status_ = kTestStatusUnknown;

  calibration_layer_->SetImage(calibration_image_a_);
  runner_context_.ApplyConfig();
  calibration_layer_->SetImage(calibration_image_b_);
  runner_context_.ApplyConfig();

  return test_context_.get();
}

void Runner::FinishTest(int32_t status) {
  test_status_ = status;
  test_running_ = false;
  loop_->Quit();
}

int32_t Runner::CleanupTest() {
  ZX_ASSERT_MSG(!test_running_, "Tried to finish running test");

  test_context_.release();
  for (auto id : buffer_ids_) {
    camera_stream_->ReleaseFrame(id);
  }
  buffer_ids_.clear();
  display_idx_ = 0;
  capture_idx_ = 0;
  for (auto frame : frames_) {
    for (auto layer : frame) {
      layer.first->DeleteState(layer.second);
    }
  }
  frames_.clear();

  return test_status_;
}

void Runner::ApplyConfig(std::vector<LayerImpl*> layers) {
  std::vector<std::pair<LayerImpl*, const void*>> info;
  for (auto l : layers) {
    info.push_back(std::make_pair(l, l->ApplyState()));
  }
  frames_.push_back(std::move(info));
}

void Runner::SendFrameConfig(uint32_t frame_idx) {
  std::vector<uint64_t> layer_ids;
  auto& frame = frames_[frame_idx];
  for (auto layer : frame) {
    layer_ids.push_back(layer.first->id());
    layer.first->SendState(layer.second);
  }
  display_controller_->SetDisplayLayers(
      display_id_, fidl::VectorPtr<uint64_t>(std::move(layer_ids)));
}

void Runner::CheckFrameConfig(uint32_t frame_idx) {
  SendFrameConfig(frame_idx);
  display_controller_->CheckConfig(
      frame_idx == frames_.size() - 1,
      [this, frame_idx](
          fuchsia::display::ConfigResult result,
          ::fidl::VectorPtr<fuchsia::display::ClientCompositionOp>) {
        if (result == fuchsia::display::ConfigResult::OK) {
          if (frame_idx + 1 < frames_.size()) {
            CheckFrameConfig(frame_idx + 1);
          } else {
            ApplyFrame(0);
          }
        } else {
          FinishTest(kTestDisplayCheckFail);
        }
      });
}

void Runner::ApplyFrame(uint32_t frame_idx) {
  SendFrameConfig(frame_idx);
  display_controller_->ApplyConfig();
}

void Runner::OnVsync(uint64_t display_id, uint64_t timestamp,
                     ::fidl::VectorPtr<uint64_t> image_ids) {
  if (!test_running_ || image_ids.get().empty()) {
    return;
  }

  auto& frame = frames_[display_idx_];
  unsigned image_idx = 0;
  for (auto layer : frame) {
    uint64_t expected_image = layer.first->image_id(layer.second);
    if (expected_image) {
      if (image_ids.get()[image_idx++] != expected_image) {
        if (display_idx_ != 0) {
          FinishTest(kTestVsyncFail);
        }
        return;
      }
    }
  }

  if (capture_idx_ > 0) {
    if (display_idx_ + 1 < frames_.size()) {
      ApplyFrame(++display_idx_);
    }
  }
}

void Runner::FrameNotifyCallback(
    const fuchsia::camera::FrameAvailableEvent& resp) {
  static int64_t last_timestamp = 0;
  last_timestamp = resp.metadata.timestamp;
  if (test_running_) {
    if (resp.frame_status != fuchsia::camera::FrameStatus::OK) {
      if (capture_idx_ != 0 || ++bad_capture_count_ > 5) {
        ZX_ASSERT_MSG(false, "Bad capture");
        FinishTest(kTestCaptureFail);
      }
    } else if (capture_idx_ < 2) {
      if (CheckFrame(capture_idx_, camera_buffers_[resp.buffer_id], true)) {
        capture_idx_++;
      }
    } else {
      buffer_ids_.push_back(resp.buffer_id);
      capture_idx_++;

      if (capture_idx_ == frames_.size()) {
        for (unsigned i = 2; i < frames_.size(); i++) {
          if (!CheckFrame(i, camera_buffers_[buffer_ids_[i - 2]], false)) {
            FinishTest(kTestCaptureMismatch);
            return;
          }
        }
        FinishTest(kTestOk);
      }

      // Don't release the frame, since we need to process it later.
      return;
    }
  }
  camera_stream_->ReleaseFrame(resp.buffer_id);
}

bool Runner::CheckFrame(uint32_t frame_idx, uint8_t* capture_ptr, bool quick) {
  static uint32_t quickcheck_coords[][2] = {
      {0, 0},
      {0, height_ - 1},
      {width_ - 2, 0},
      {width_ - 2, height_ - 1},
      {width_ / 2, height_ / 2},
      {UINT32_MAX, UINT32_MAX},
  };
  uint32_t quick_idx = 0;
  uint32_t x = 0;
  uint32_t y = 0;

  while (y < height_ && x < width_) {
    uint32_t expected_rgb = 0;
    bool first_layer = true;
    bool skip = false;
    for (auto layer : frames_[frame_idx]) {
      bool layer_skip;
      uint32_t layer_color;
      bool has_pixel =
          layer.first->GetPixel(layer.second, x, y, &layer_color, &layer_skip);
      if (!has_pixel) {
        continue;
      }

      if (first_layer) {
        ZX_ASSERT(is_opaque(layer_color));
        first_layer = false;
      }

      if (layer_skip) {
        skip = true;
      } else if (skip && is_opaque(layer_color)) {
        skip = false;
      }

      expected_rgb = multiply(expected_rgb, layer_color);
    }

    // There must be some fully opaque pixel
    ZX_ASSERT(!first_layer);

    if (!skip) {
      uint32_t actual_rgb1, actual_rgb2;
      // 2 bytes per pixel, so offset by x * 2
      yuy2_to_bgra(capture_ptr + (y * camera_stride_) + (x * 2), &actual_rgb1,
                   &actual_rgb2);

      if (!compare_colors(expected_rgb, actual_rgb1) ||
          !compare_colors(expected_rgb, actual_rgb2)) {
        if (!quick) {
          printf("Mismatch (%d, %d) %08x=%08x,%08x\n", x, y, expected_rgb,
                 actual_rgb1, actual_rgb2);
        }
        return false;
      }
    }

    if (quick) {
      ++quick_idx;
      x = quickcheck_coords[quick_idx][0];
      y = quickcheck_coords[quick_idx][1];
    } else {
      // Check a macropixel at a time, so += 2
      x += 2;
      if (x == width_) {
        x = 0;
        y++;
      }
    }
  }
  return true;
}

}  // namespace internal
}  // namespace display_test
