// Copyright 2017 The Chromium OS 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 "camera3_test/camera3_still_capture_fixture.h"

#include <algorithm>

#include <base/stl_util.h>
#include <base/files/file_util.h>
#include <base/command_line.h>

namespace camera3_test {

void Camera3StillCaptureFixture::SetUp() {
  ASSERT_EQ(
      0, cam_service_.Initialize(
             base::Bind(&Camera3StillCaptureFixture::ProcessStillCaptureResult,
                        base::Unretained(this)),
             Camera3Service::ProcessRecordingResultCallback()))
      << "Failed to initialize camera service";
  for (const auto& it : cam_ids_) {
    jpeg_max_sizes_[it] = cam_service_.GetStaticInfo(it)->GetJpegMaxSize();
  }
}

void Camera3StillCaptureFixture::ProcessStillCaptureResult(
    int cam_id,
    uint32_t frame_number,
    ScopedCameraMetadata metadata,
    ScopedBufferHandle buffer) {
  VLOGF_ENTER();
  StillCaptureResult* result = &still_capture_results_[cam_id];
  result->result_metadatas.emplace_back(std::move(metadata));
  result->buffer_handles.emplace_back(std::move(buffer));

  time_t cur_time;
  time(&cur_time);
  result->result_date_time.push_back(cur_time);
  sem_post(&result->capture_result_sem);
}

int Camera3StillCaptureFixture::WaitStillCaptureResult(
    int cam_id, const struct timespec& timeout) {
  // Wait for capture result callback
  return sem_timedwait(&still_capture_results_[cam_id].capture_result_sem,
                       &timeout);
}

Camera3StillCaptureFixture::StillCaptureResult::StillCaptureResult() {
  sem_init(&capture_result_sem, 0, 0);
}

Camera3StillCaptureFixture::StillCaptureResult::~StillCaptureResult() {
  sem_destroy(&capture_result_sem);
}

// Test parameters:
// - Camera ID
class Camera3SimpleStillCaptureTest
    : public Camera3StillCaptureFixture,
      public ::testing::WithParamInterface<int32_t> {
 public:
  Camera3SimpleStillCaptureTest()
      : Camera3StillCaptureFixture(std::vector<int>(1, GetParam())),
        cam_id_(GetParam()) {}

 protected:
  using ExifTestData = Camera3ExifValidator::ExifTestData;

  int cam_id_;

  void TakePictureTest(uint32_t num_still_pictures,
                       bool require_3a_converged = true);
};

TEST_P(Camera3SimpleStillCaptureTest, JpegExifTest) {
  // Reference:
  // camera2/cts/StillCaptureTest.java.java#testJpegExif
  ResolutionInfo jpeg_resolution =
      cam_service_.GetStaticInfo(cam_id_)
          ->GetSortedOutputResolutions(HAL_PIXEL_FORMAT_BLOB)
          .back();
  std::vector<ResolutionInfo> thumbnail_resolutions;
  EXPECT_TRUE(cam_service_.GetStaticInfo(cam_id_)->GetAvailableThumbnailSizes(
                  &thumbnail_resolutions) == 0 &&
              !thumbnail_resolutions.empty())
      << "JPEG thumbnail sizes are not available";
  // Size must contain (0, 0).
  EXPECT_TRUE(std::find(thumbnail_resolutions.begin(),
                        thumbnail_resolutions.end(),
                        ResolutionInfo(0, 0)) != thumbnail_resolutions.end())
      << "JPEG thumbnail sizes should contain (0, 0)";
  // Each size must be distinct.
  EXPECT_EQ(thumbnail_resolutions.size(),
            std::set<ResolutionInfo>(thumbnail_resolutions.begin(),
                                     thumbnail_resolutions.end())
                .size())
      << "JPEG thumbnail sizes contain duplicate items";
  // Must be sorted in ascending order by area, by width if areas are same.
  EXPECT_TRUE(std::is_sorted(thumbnail_resolutions.begin(),
                             thumbnail_resolutions.end()))
      << "JPEG thumbnail sizes are not in ascending order";

  ResolutionInfo preview_resolution =
      cam_service_.GetStaticInfo(cam_id_)
          ->GetSortedOutputResolutions(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)
          .back();
  ResolutionInfo recording_resolution(0, 0);
  ASSERT_EQ(
      0, cam_service_.StartPreview(cam_id_, preview_resolution, jpeg_resolution,
                                   recording_resolution));

  ExifTestData exif_test_data[] = {
      {thumbnail_resolutions.front(), 90, 80, 75},
      {thumbnail_resolutions.front(), 180, 90, 85},
      {thumbnail_resolutions.back(), 270, 100, 100},
  };

  ScopedCameraMetadata metadata(
      clone_camera_metadata(cam_service_.ConstructDefaultRequestSettings(
          cam_id_, CAMERA3_TEMPLATE_STILL_CAPTURE)));
  ASSERT_NE(nullptr, metadata.get())
      << "Failed to create still capture metadata";
  for (const auto& it : exif_test_data) {
#define ARRAY_SIZE(A) (sizeof(A) / sizeof(*(A)))
    int32_t thumbnail_resolution[] = {it.thumbnail_resolution.Width(),
                                      it.thumbnail_resolution.Height()};
    EXPECT_EQ(0,
              UpdateMetadata(ANDROID_JPEG_THUMBNAIL_SIZE, thumbnail_resolution,
                             ARRAY_SIZE(thumbnail_resolution), &metadata));
    EXPECT_EQ(0, UpdateMetadata(ANDROID_JPEG_ORIENTATION, &it.orientation, 1,
                                &metadata));
    EXPECT_EQ(0, UpdateMetadata(ANDROID_JPEG_QUALITY, &it.jpeg_quality, 1,
                                &metadata));
    EXPECT_EQ(0, UpdateMetadata(ANDROID_JPEG_THUMBNAIL_QUALITY,
                                &it.thumbnail_quality, 1, &metadata));
    cam_service_.TakeStillCapture(cam_id_, metadata.get());
  }

  struct timespec timeout;
  clock_gettime(CLOCK_REALTIME, &timeout);
  timeout.tv_sec += ARRAY_SIZE(exif_test_data);  // 1 second per capture
  for (size_t i = 0; i < base::size(exif_test_data); i++) {
    ASSERT_EQ(0, WaitStillCaptureResult(cam_id_, timeout))
        << "Waiting for still capture result timeout";
  }

  Camera3ExifValidator exif_test(*cam_service_.GetStaticInfo(cam_id_));
  for (size_t i = 0;
       i < still_capture_results_[cam_id_].result_metadatas.size(); i++) {
    exif_test.ValidateExifKeys(
        jpeg_resolution, exif_test_data[i],
        still_capture_results_[cam_id_].buffer_handles[i],
        jpeg_max_sizes_[cam_id_],
        *still_capture_results_[cam_id_].result_metadatas[i].get(),
        still_capture_results_[cam_id_].result_date_time[i]);
  }
  cam_service_.StopPreview(cam_id_);
}

void Camera3SimpleStillCaptureTest::TakePictureTest(uint32_t num_still_pictures,
                                                    bool require_3a_converged) {
  auto IsAFSupported = [this]() {
    std::vector<uint8_t> available_af_modes;
    cam_service_.GetStaticInfo(cam_id_)->GetAvailableAFModes(
        &available_af_modes);
    uint8_t af_modes[] = {ANDROID_CONTROL_AF_MODE_AUTO,
                          ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE,
                          ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO,
                          ANDROID_CONTROL_AF_MODE_MACRO};
    for (const auto& it : af_modes) {
      if (std::find(available_af_modes.begin(), available_af_modes.end(), it) !=
          available_af_modes.end()) {
        return true;
      }
    }
    return false;
  };

  ResolutionInfo jpeg_resolution =
      cam_service_.GetStaticInfo(cam_id_)
          ->GetSortedOutputResolutions(HAL_PIXEL_FORMAT_BLOB)
          .back();
  ResolutionInfo preview_resolution =
      cam_service_.GetStaticInfo(cam_id_)
          ->GetSortedOutputResolutions(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)
          .back();
  ResolutionInfo recording_resolution(0, 0);
  ASSERT_EQ(
      0, cam_service_.StartPreview(cam_id_, preview_resolution, jpeg_resolution,
                                   recording_resolution));

  // Trigger an auto focus run, and wait for AF locked.
  if (IsAFSupported()) {
    cam_service_.StartAutoFocus(cam_id_);
    int af_result = cam_service_.WaitForAutoFocusDone(cam_id_);
    if (require_3a_converged) {
      ASSERT_EQ(0, af_result) << "Wait for auto focus done timed out";
    } else if (af_result != 0) {
      LOGF(WARNING) << "Ignore AF converged timeout failure.";
    }
  }
  // Wait for AWB converged, then lock it.
  int awb_result = cam_service_.WaitForAWBConvergedAndLock(cam_id_);
  if (require_3a_converged) {
    ASSERT_EQ(0, awb_result) << "Wait for AWB converged timed out";
  } else if (awb_result != 0) {
    LOGF(WARNING) << "Ignore AWB converged timeout failure.";
  }
  // Trigger an AE precapture metering sequence and wait for AE converged.
  cam_service_.StartAEPrecapture(cam_id_);
  int ae_result = cam_service_.WaitForAEStable(cam_id_);
  if (require_3a_converged) {
    ASSERT_EQ(0, ae_result) << "Wait for AE stable timed out";
  } else if (ae_result != 0) {
    LOGF(WARNING) << "Ignore AE converged timeout failure.";
  }

  const camera_metadata_t* metadata =
      cam_service_.ConstructDefaultRequestSettings(
          cam_id_, CAMERA3_TEMPLATE_STILL_CAPTURE);
  for (uint32_t i = 0; i < num_still_pictures; i++) {
    cam_service_.TakeStillCapture(cam_id_, metadata);
  }

  cam_service_.StopPreview(cam_id_);
}

TEST_P(Camera3SimpleStillCaptureTest, TakePictureTest) {
  TakePictureTest(1);
}

TEST_P(Camera3SimpleStillCaptureTest, PerformanceTest) {
  TakePictureTest(2);
}

// Test parameters:
// - Camera ID
class Camera3DumpSimpleStillCaptureTest : public Camera3SimpleStillCaptureTest {
 public:
  Camera3DumpSimpleStillCaptureTest() : dump_path_(GetCommandLineDumpPath()) {}

  void ProcessStillCaptureResult(int cam_id,
                                 uint32_t frame_number,
                                 ScopedCameraMetadata metadata,
                                 ScopedBufferHandle buffer) override;

 protected:
  base::FilePath dump_path_;

  inline base::FilePath GetCommandLineDumpPath() {
    return base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
        "dump_still_capture_path");
  }
};

void Camera3DumpSimpleStillCaptureTest::ProcessStillCaptureResult(
    int cam_id,
    uint32_t frame_number,
    ScopedCameraMetadata metadata,
    ScopedBufferHandle buffer) {
  size_t jpeg_max_size = jpeg_max_sizes_[cam_id_];
  void* buf_addr = nullptr;
  ASSERT_EQ(0, Camera3TestGralloc::GetInstance()->Lock(
                   *buffer, 0, 0, 0, jpeg_max_size, 1, &buf_addr));
  ASSERT_NE(nullptr, buf_addr);

  {
    // Ensure buffer unlock process is executed when exiting from ASSERT_XX.
    struct UnlockBuf {
      void operator()(buffer_handle_t* handle) {
        Camera3TestGralloc::GetInstance()->Unlock(*handle);
      }
    };
    std::unique_ptr<buffer_handle_t, UnlockBuf> unlock(buffer.get());

    auto jpeg_blob = reinterpret_cast<camera3_jpeg_blob_t*>(
        static_cast<uint8_t*>(buf_addr) + jpeg_max_size -
        sizeof(camera3_jpeg_blob_t));
    ASSERT_LE(buf_addr, static_cast<void*>(jpeg_blob));
    ASSERT_EQ(CAMERA3_JPEG_BLOB_ID, jpeg_blob->jpeg_blob_id);

    auto jpeg_size = jpeg_blob->jpeg_size;
    ASSERT_EQ(jpeg_size,
              base::WriteFile(dump_path_, static_cast<const char*>(buf_addr),
                              jpeg_size));
  }
}

TEST_P(Camera3DumpSimpleStillCaptureTest, DumpCaptureResult) {
  // Run only if --dump_still_capture_path argument presented.
  if (dump_path_.empty()) {
    GTEST_SKIP();
  }
  TakePictureTest(1, /*require_3a_converged=*/false);
}

// Test parameters:
// - Camera ID, preview resolution, JPEG resolution
class Camera3JpegResolutionTest
    : public Camera3StillCaptureFixture,
      public ::testing::WithParamInterface<
          std::tuple<int32_t, ResolutionInfo, ResolutionInfo>> {
 public:
  Camera3JpegResolutionTest()
      : Camera3StillCaptureFixture(
            std::vector<int>(1, std::get<0>(GetParam()))),
        cam_id_(std::get<0>(GetParam())) {}

 protected:
  int cam_id_;
};

TEST_P(Camera3JpegResolutionTest, JpegResolutionTest) {
  ResolutionInfo preview_resolution(std::get<1>(GetParam()));
  ResolutionInfo jpeg_resolution(std::get<2>(GetParam()));
  VLOGF(1) << "Device " << cam_id_;
  VLOGF(1) << "Preview resolution " << preview_resolution.Width() << "x"
           << preview_resolution.Height();
  VLOGF(1) << "JPEG resolution " << jpeg_resolution.Width() << "x"
           << jpeg_resolution.Height();

  ResolutionInfo recording_resolution(0, 0);
  ASSERT_EQ(
      0, cam_service_.StartPreview(cam_id_, preview_resolution, jpeg_resolution,
                                   recording_resolution));
  ScopedCameraMetadata metadata(
      clone_camera_metadata(cam_service_.ConstructDefaultRequestSettings(
          cam_id_, CAMERA3_TEMPLATE_STILL_CAPTURE)));
  ASSERT_NE(nullptr, metadata.get())
      << "Failed to create still capture metadata";
  cam_service_.TakeStillCapture(cam_id_, metadata.get());
  cam_service_.StopPreview(cam_id_);

  ASSERT_EQ(1, still_capture_results_[cam_id_].buffer_handles.size())
      << "Incorrect number of still captures received";
  JpegExifInfo jpeg_exif_info(still_capture_results_[cam_id_].buffer_handles[0],
                              jpeg_max_sizes_[cam_id_]);
  ASSERT_TRUE(jpeg_exif_info.Initialize());
  EXPECT_EQ(jpeg_resolution, jpeg_exif_info.jpeg_resolution)
      << "JPEG size result and request should match";
}

INSTANTIATE_TEST_SUITE_P(
    Camera3StillCaptureTest,
    Camera3SimpleStillCaptureTest,
    ::testing::ValuesIn(Camera3Module().GetTestCameraIds()));

static std::vector<std::tuple<int, ResolutionInfo, ResolutionInfo>>
IterateCameraIdPreviewJpegResolution() {
  std::vector<std::tuple<int, ResolutionInfo, ResolutionInfo>> result;
  auto cam_ids = Camera3Module().GetTestCameraIds();
  for (const auto& cam_id : cam_ids) {
    auto preview_resolutions = Camera3Module().GetSortedOutputResolutions(
        cam_id, HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED);
    auto jpeg_resolutions = Camera3Module().GetSortedOutputResolutions(
        cam_id, HAL_PIXEL_FORMAT_BLOB);
    for (const auto& preview_resolution : preview_resolutions) {
      for (const auto& jpeg_resolution : jpeg_resolutions) {
        result.emplace_back(cam_id, preview_resolution, jpeg_resolution);
      }
    }
  }
  return result;
}

INSTANTIATE_TEST_SUITE_P(
    Camera3StillCaptureTest,
    Camera3JpegResolutionTest,
    ::testing::ValuesIn(IterateCameraIdPreviewJpegResolution()));

INSTANTIATE_TEST_SUITE_P(
    Camera3StillCaptureTest,
    Camera3DumpSimpleStillCaptureTest,
    ::testing::ValuesIn(Camera3Module().GetTestCameraIds()));

}  // namespace camera3_test
