// 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;
  buffer_collection.format.set_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_status_t status) {
    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
