/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//#define LOG_NDEBUG 0
#define LOG_TAG "EmulatedCameraDeviceHwlImpl"
#include "EmulatedCameraDeviceHWLImpl.h"

#include <hardware/camera_common.h>
#include <log/log.h>

#include "EmulatedCameraDeviceSessionHWLImpl.h"
#include "utils/HWLUtils.h"

namespace android {

std::unique_ptr<CameraDeviceHwl> EmulatedCameraDeviceHwlImpl::Create(
    uint32_t camera_id, std::unique_ptr<HalCameraMetadata> static_meta,
    PhysicalDeviceMapPtr physical_devices,
    std::shared_ptr<EmulatedTorchState> torch_state) {
  auto device = std::unique_ptr<EmulatedCameraDeviceHwlImpl>(
      new EmulatedCameraDeviceHwlImpl(camera_id, std::move(static_meta),
                                      std::move(physical_devices),
                                      torch_state));

  if (device == nullptr) {
    ALOGE("%s: Creating EmulatedCameraDeviceHwlImpl failed.", __FUNCTION__);
    return nullptr;
  }

  status_t res = device->Initialize();
  if (res != OK) {
    ALOGE("%s: Initializing EmulatedCameraDeviceHwlImpl failed: %s (%d).",
          __FUNCTION__, strerror(-res), res);
    return nullptr;
  }

  ALOGI("%s: Created EmulatedCameraDeviceHwlImpl for camera %u", __FUNCTION__,
        device->camera_id_);

  return device;
}

EmulatedCameraDeviceHwlImpl::EmulatedCameraDeviceHwlImpl(
    uint32_t camera_id, std::unique_ptr<HalCameraMetadata> static_meta,
    PhysicalDeviceMapPtr physical_devices,
    std::shared_ptr<EmulatedTorchState> torch_state)
    : camera_id_(camera_id),
      static_metadata_(std::move(static_meta)),
      physical_device_map_(std::move(physical_devices)),
      torch_state_(torch_state) {}

uint32_t EmulatedCameraDeviceHwlImpl::GetCameraId() const {
  return camera_id_;
}

status_t EmulatedCameraDeviceHwlImpl::Initialize() {
  auto ret = GetSensorCharacteristics(static_metadata_.get(),
                                      &sensor_chars_[camera_id_]);
  if (ret != OK) {
    ALOGE("%s: Unable to extract sensor characteristics %s (%d)", __FUNCTION__,
          strerror(-ret), ret);
    return ret;
  }

  stream_configuration_map_ =
      std::make_unique<StreamConfigurationMap>(*static_metadata_);
  stream_configuration_map_max_resolution_ =
      std::make_unique<StreamConfigurationMap>(*static_metadata_,
                                               /*maxResolution*/ true);

  for (const auto& it : *physical_device_map_) {
    uint32_t physical_id = it.first;
    HalCameraMetadata* physical_hal_metadata = it.second.second.get();
    physical_stream_configuration_map_.emplace(
        physical_id,
        std::make_unique<StreamConfigurationMap>(*physical_hal_metadata));
    physical_stream_configuration_map_max_resolution_.emplace(
        physical_id, std::make_unique<StreamConfigurationMap>(
                         *physical_hal_metadata, /*maxResolution*/ true));

    ret = GetSensorCharacteristics(physical_hal_metadata,
                                   &sensor_chars_[physical_id]);
    if (ret != OK) {
      ALOGE("%s: Unable to extract camera %d sensor characteristics %s (%d)",
            __FUNCTION__, physical_id, strerror(-ret), ret);
      return ret;
    }
  }

  default_torch_strength_level_ = GetDefaultTorchStrengthLevel();
  maximum_torch_strength_level_ = GetMaximumTorchStrengthLevel();
  return OK;
}

status_t EmulatedCameraDeviceHwlImpl::GetResourceCost(
    CameraResourceCost* cost) const {
  // TODO: remove hardcode
  cost->resource_cost = 100;

  return OK;
}

status_t EmulatedCameraDeviceHwlImpl::GetCameraCharacteristics(
    std::unique_ptr<HalCameraMetadata>* characteristics) const {
  if (characteristics == nullptr) {
    return BAD_VALUE;
  }

  *characteristics = HalCameraMetadata::Clone(static_metadata_.get());

  return OK;
}

status_t EmulatedCameraDeviceHwlImpl::GetPhysicalCameraCharacteristics(
    uint32_t physical_camera_id,
    std::unique_ptr<HalCameraMetadata>* characteristics) const {
  if (characteristics == nullptr) {
    return BAD_VALUE;
  }

  if (physical_device_map_.get() == nullptr) {
    ALOGE("%s: Camera %d is not a logical device!", __func__, camera_id_);
    return NO_INIT;
  }

  if (physical_device_map_->find(physical_camera_id) ==
      physical_device_map_->end()) {
    ALOGE("%s: Physical camera id %d is not part of logical camera %d!",
          __func__, physical_camera_id, camera_id_);
    return BAD_VALUE;
  }

  *characteristics = HalCameraMetadata::Clone(
      physical_device_map_->at(physical_camera_id).second.get());

  return OK;
}

status_t EmulatedCameraDeviceHwlImpl::SetTorchMode(TorchMode mode) {
  if (torch_state_.get() == nullptr) {
    return INVALID_OPERATION;
  }

  // If torch strength control is supported, reset the torch strength level to
  // default level whenever the torch is turned OFF.
  if (maximum_torch_strength_level_ > 1) {
    torch_state_->InitializeTorchDefaultLevel(default_torch_strength_level_);
    torch_state_->InitializeSupportTorchStrengthLevel(true);
  }

  return torch_state_->SetTorchMode(mode);
}

status_t EmulatedCameraDeviceHwlImpl::TurnOnTorchWithStrengthLevel(int32_t torch_strength) {
  if (torch_state_.get() == nullptr) {
    return UNKNOWN_TRANSACTION;
  }

  // This API is supported if the maximum level is set to greater than 1.
  if (maximum_torch_strength_level_ <= 1) {
    ALOGE("Torch strength control feature is not supported.");
    return UNKNOWN_TRANSACTION;
  }
  // Validate that the torch_strength is within the range.
  if (torch_strength > maximum_torch_strength_level_ || torch_strength < 1) {
    ALOGE("Torch strength value should be within the range.");
    return BAD_VALUE;
  }

  return torch_state_->TurnOnTorchWithStrengthLevel(torch_strength);
}

status_t EmulatedCameraDeviceHwlImpl::GetTorchStrengthLevel(int32_t& torch_strength) const {
  if (default_torch_strength_level_ < 1 && maximum_torch_strength_level_ <= 1) {
    ALOGE("Torch strength control feature is not supported.");
    return UNKNOWN_TRANSACTION;
  }

  torch_strength = torch_state_->GetTorchStrengthLevel();
  ALOGV("Current torch strength level is: %d", torch_strength);
  return OK;
}

status_t EmulatedCameraDeviceHwlImpl::DumpState(int /*fd*/) {
  return OK;
}

status_t EmulatedCameraDeviceHwlImpl::CreateCameraDeviceSessionHwl(
    CameraBufferAllocatorHwl* /*camera_allocator_hwl*/,
    std::unique_ptr<CameraDeviceSessionHwl>* session) {
  if (session == nullptr) {
    ALOGE("%s: session is nullptr.", __FUNCTION__);
    return BAD_VALUE;
  }

  std::unique_ptr<HalCameraMetadata> meta =
      HalCameraMetadata::Clone(static_metadata_.get());
  *session = EmulatedCameraDeviceSessionHwlImpl::Create(
      camera_id_, std::move(meta), ClonePhysicalDeviceMap(physical_device_map_),
      torch_state_);
  if (*session == nullptr) {
    ALOGE("%s: Cannot create EmulatedCameraDeviceSessionHWlImpl.", __FUNCTION__);
    return BAD_VALUE;
  }

  if (torch_state_.get() != nullptr) {
    torch_state_->AcquireFlashHw();
  }

  return OK;
}

bool EmulatedCameraDeviceHwlImpl::IsStreamCombinationSupported(
    const StreamConfiguration& stream_config) {
  return EmulatedSensor::IsStreamCombinationSupported(
      camera_id_, stream_config, *stream_configuration_map_,
      *stream_configuration_map_max_resolution_,
      physical_stream_configuration_map_,
      physical_stream_configuration_map_max_resolution_, sensor_chars_);
}

int32_t EmulatedCameraDeviceHwlImpl::GetDefaultTorchStrengthLevel() const {
  camera_metadata_ro_entry entry;
  int32_t default_level = 0;
  auto ret = static_metadata_->Get(ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL, &entry);
  if (ret == OK && (entry.count == 1)) {
     default_level = *entry.data.i32;
     ALOGV("Default torch strength level is %d", default_level);
  }
  return default_level;
}

int32_t EmulatedCameraDeviceHwlImpl::GetMaximumTorchStrengthLevel() const {
  camera_metadata_ro_entry entry;
  int32_t max_level = 0;
  auto ret = static_metadata_->Get(ANDROID_FLASH_INFO_STRENGTH_MAXIMUM_LEVEL, &entry);
  if (ret == OK && (entry.count == 1)) {
     max_level = *entry.data.i32;
     ALOGV("Maximum torch strength level is %d", max_level);
  }
  return max_level;
}

}  // namespace android
