// Copyright 2017 The Chromium 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 "media/capture/video/chromeos/camera_device_context.h"

#include "base/strings/string_number_conversions.h"
#include "media/capture/video/chromeos/video_capture_features_chromeos.h"

namespace media {

CameraDeviceContext::CameraDeviceContext()
    : state_(State::kStopped),
      sensor_orientation_(0),
      screen_rotation_(0),
      frame_rotation_at_source_(true) {
  DETACH_FROM_SEQUENCE(sequence_checker_);
}

CameraDeviceContext::~CameraDeviceContext() = default;

bool CameraDeviceContext::AddClient(
    ClientType client_type,
    std::unique_ptr<VideoCaptureDevice::Client> client) {
  DCHECK(client);
  base::AutoLock lock(client_lock_);
  if (!clients_.insert({client_type, std::move(client)}).second) {
    SetErrorState(
        media::VideoCaptureError::kCrosHalV3DeviceContextDuplicatedClient,
        FROM_HERE,
        std::string("Duplicated client in camera device context: ") +
            base::NumberToString(static_cast<uint32_t>(client_type)));
    return false;
  }
  return true;
}

void CameraDeviceContext::RemoveClient(ClientType client_type) {
  base::AutoLock lock(client_lock_);
  auto client = clients_.find(client_type);
  if (client == clients_.end()) {
    return;
  }
  clients_.erase(client);
}

void CameraDeviceContext::SetState(State state) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  state_ = state;
  if (state_ == State::kCapturing) {
    base::AutoLock lock(client_lock_);
    for (const auto& client : clients_) {
      client.second->OnStarted();
    }
  }
}

CameraDeviceContext::State CameraDeviceContext::GetState() {
  return state_;
}

void CameraDeviceContext::SetErrorState(media::VideoCaptureError error,
                                        const base::Location& from_here,
                                        const std::string& reason) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  state_ = State::kError;
  LOG(ERROR) << from_here.ToString() << ": " << reason;
  base::AutoLock lock(client_lock_);
  for (const auto& client : clients_) {
    client.second->OnError(error, from_here, reason);
  }
}

void CameraDeviceContext::LogToClient(std::string message) {
  base::AutoLock lock(client_lock_);
  for (const auto& client : clients_) {
    client.second->OnLog(message);
  }
}

void CameraDeviceContext::SubmitCapturedVideoCaptureBuffer(
    ClientType client_type,
    VideoCaptureDevice::Client::Buffer buffer,
    const VideoCaptureFormat& frame_format,
    base::TimeTicks reference_time,
    base::TimeDelta timestamp,
    const VideoFrameMetadata& metadata) {
  base::AutoLock lock(client_lock_);
  auto client = clients_.find(client_type);
  if (client == clients_.end()) {
    return;
  }

  client->second->OnIncomingCapturedBufferExt(
      std::move(buffer), frame_format, gfx::ColorSpace(), reference_time,
      timestamp, gfx::Rect(frame_format.frame_size), std::move(metadata));
}

void CameraDeviceContext::SubmitCapturedGpuMemoryBuffer(
    ClientType client_type,
    gfx::GpuMemoryBuffer* buffer,
    const VideoCaptureFormat& frame_format,
    base::TimeTicks reference_time,
    base::TimeDelta timestamp) {
  base::AutoLock lock(client_lock_);
  auto client = clients_.find(client_type);
  if (client == clients_.end()) {
    return;
  }

  client->second->OnIncomingCapturedGfxBuffer(buffer, frame_format,
                                              GetCameraFrameRotation(),
                                              reference_time, timestamp);
}

void CameraDeviceContext::SetSensorOrientation(int sensor_orientation) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(sensor_orientation >= 0 && sensor_orientation < 360 &&
         sensor_orientation % 90 == 0);
  base::AutoLock lock(rotation_state_lock_);
  sensor_orientation_ = sensor_orientation;
}

void CameraDeviceContext::SetScreenRotation(int screen_rotation) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(screen_rotation >= 0 && screen_rotation < 360 &&
         screen_rotation % 90 == 0);
  base::AutoLock lock(rotation_state_lock_);
  screen_rotation_ = screen_rotation;
}

void CameraDeviceContext::SetCameraFrameRotationEnabledAtSource(
    bool is_enabled) {
  base::AutoLock lock(rotation_state_lock_);
  frame_rotation_at_source_ = is_enabled;
}

int CameraDeviceContext::GetCameraFrameRotation() {
  base::AutoLock lock(rotation_state_lock_);
  return (sensor_orientation_ + screen_rotation_) % 360;
}

bool CameraDeviceContext::IsCameraFrameRotationEnabledAtSource() {
  base::AutoLock lock(rotation_state_lock_);
  return !base::FeatureList::IsEnabled(
             features::kDisableCameraFrameRotationAtSource) &&
         frame_rotation_at_source_;
}

bool CameraDeviceContext::ReserveVideoCaptureBufferFromPool(
    ClientType client_type,
    gfx::Size size,
    VideoPixelFormat format,
    VideoCaptureDevice::Client::Buffer* buffer) {
  base::AutoLock lock(client_lock_);
  auto client = clients_.find(client_type);
  if (client == clients_.end()) {
    return false;
  }

  // Use a dummy frame feedback id as we don't need it.
  constexpr int kDummyFrameFeedbackId = 0;
  auto result = client->second->ReserveOutputBuffer(
      size, format, kDummyFrameFeedbackId, buffer);
  return result == VideoCaptureDevice::Client::ReserveResult::kSucceeded;
}

bool CameraDeviceContext::HasClient() {
  base::AutoLock lock(client_lock_);
  return !clients_.empty();
}

}  // namespace media
