/*
 * Copyright (C) 2012 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.
 */

/*
 * Contains implementation of a class EmulatedCamera that encapsulates
 * functionality common to all version 2.0 emulated camera devices.  Instances
 * of this class (for each emulated camera) are created during the construction
 * of the EmulatedCameraFactory instance.  This class serves as an entry point
 * for all camera API calls that defined by camera2_device_ops_t API.
 */

#define LOG_NDEBUG 0
#define LOG_TAG "EmulatedCamera2_Camera"
#include <log/log.h>

#include "EmulatedCamera2.h"
#include "system/camera_metadata.h"

namespace android {

/* Constructs EmulatedCamera2 instance.
 * Param:
 *  cameraId - Zero based camera identifier, which is an index of the camera
 *      instance in camera factory's array.
 *  module - Emulated camera HAL module descriptor.
 */
EmulatedCamera2::EmulatedCamera2(int cameraId, struct hw_module_t *module)
    : EmulatedBaseCamera(cameraId, CAMERA_DEVICE_API_VERSION_2_0, &common,
                         module) {
  common.close = EmulatedCamera2::close;
  ops = &sDeviceOps;
  priv = this;

  mNotifyCb = NULL;

  mRequestQueueSrc = NULL;
  mFrameQueueDst = NULL;

  mVendorTagOps.get_camera_vendor_section_name =
      EmulatedCamera2::get_camera_vendor_section_name;
  mVendorTagOps.get_camera_vendor_tag_name =
      EmulatedCamera2::get_camera_vendor_tag_name;
  mVendorTagOps.get_camera_vendor_tag_type =
      EmulatedCamera2::get_camera_vendor_tag_type;
  mVendorTagOps.parent = this;

  mStatusPresent = true;
}

/* Destructs EmulatedCamera2 instance. */
EmulatedCamera2::~EmulatedCamera2() {}

/****************************************************************************
 * Abstract API
 ***************************************************************************/

/****************************************************************************
 * Public API
 ***************************************************************************/

status_t EmulatedCamera2::Initialize(const cvd::CameraDefinition & /*props*/) {
  return NO_ERROR;
}

/****************************************************************************
 * Camera API implementation
 ***************************************************************************/

status_t EmulatedCamera2::connectCamera(hw_device_t **device) {
  *device = &common;
  return NO_ERROR;
}

status_t EmulatedCamera2::closeCamera() { return NO_ERROR; }

status_t EmulatedCamera2::getCameraInfo(struct camera_info *info) {
  return EmulatedBaseCamera::getCameraInfo(info);
}

/****************************************************************************
 * Camera Device API implementation.
 * These methods are called from the camera API callback routines.
 ***************************************************************************/

/** Request input queue */

int EmulatedCamera2::requestQueueNotify() { return INVALID_OPERATION; }

/** Count of requests in flight */
int EmulatedCamera2::getInProgressCount() { return INVALID_OPERATION; }

/** Cancel all captures in flight */
int EmulatedCamera2::flushCapturesInProgress() { return INVALID_OPERATION; }

/** Construct a default request for a given use case */
int EmulatedCamera2::constructDefaultRequest(int /*request_template*/,
                                             camera_metadata_t ** /*request*/) {
  return INVALID_OPERATION;
}

/** Output stream creation and management */

int EmulatedCamera2::allocateStream(uint32_t /*width*/, uint32_t /*height*/,
                                    int /*format*/,
                                    const camera2_stream_ops_t * /*stream_ops*/,
                                    uint32_t * /*stream_id*/,
                                    uint32_t * /*format_actual*/,
                                    uint32_t * /*usage*/,
                                    uint32_t * /*max_buffers*/) {
  return INVALID_OPERATION;
}

int EmulatedCamera2::registerStreamBuffers(uint32_t /*stream_id*/,
                                           int /*num_buffers*/,
                                           buffer_handle_t * /*buffers*/) {
  return INVALID_OPERATION;
}

int EmulatedCamera2::releaseStream(uint32_t /*stream_id*/) {
  return INVALID_OPERATION;
}

/** Reprocessing input stream management */

int EmulatedCamera2::allocateReprocessStream(
    uint32_t /*width*/, uint32_t /*height*/, uint32_t /*format*/,
    const camera2_stream_in_ops_t * /*reprocess_stream_ops*/,
    uint32_t * /*stream_id*/, uint32_t * /*consumer_usage*/,
    uint32_t * /*max_buffers*/) {
  return INVALID_OPERATION;
}

int EmulatedCamera2::allocateReprocessStreamFromStream(
    uint32_t /*output_stream_id*/,
    const camera2_stream_in_ops_t * /*reprocess_stream_ops*/,
    uint32_t * /*stream_id*/) {
  return INVALID_OPERATION;
}

int EmulatedCamera2::releaseReprocessStream(uint32_t /*stream_id*/) {
  return INVALID_OPERATION;
}

/** 3A triggering */

int EmulatedCamera2::triggerAction(uint32_t /*trigger_id*/, int /*ext1*/,
                                   int /*ext2*/) {
  return INVALID_OPERATION;
}

/** Custom tag query methods */

const char *EmulatedCamera2::getVendorSectionName(uint32_t /*tag*/) {
  return NULL;
}

const char *EmulatedCamera2::getVendorTagName(uint32_t /*tag*/) { return NULL; }

int EmulatedCamera2::getVendorTagType(uint32_t /*tag*/) { return -1; }

/** Debug methods */

int EmulatedCamera2::dump(int /*fd*/) { return INVALID_OPERATION; }

/****************************************************************************
 * Private API.
 ***************************************************************************/

/****************************************************************************
 * Camera API callbacks as defined by camera2_device_ops structure.  See
 * hardware/libhardware/include/hardware/camera2.h for information on each
 * of these callbacks. Implemented in this class, these callbacks simply
 * dispatch the call into an instance of EmulatedCamera2 class defined by the
 * 'camera_device2' parameter, or set a member value in the same.
 ***************************************************************************/

EmulatedCamera2 *getInstance(const camera2_device_t *d) {
  const EmulatedCamera2 *cec = static_cast<const EmulatedCamera2 *>(d);
  return const_cast<EmulatedCamera2 *>(cec);
}

int EmulatedCamera2::set_request_queue_src_ops(
    const camera2_device_t *d,
    const camera2_request_queue_src_ops *queue_src_ops) {
  EmulatedCamera2 *ec = getInstance(d);
  ec->mRequestQueueSrc = queue_src_ops;
  return NO_ERROR;
}

int EmulatedCamera2::notify_request_queue_not_empty(const camera2_device_t *d) {
  EmulatedCamera2 *ec = getInstance(d);
  return ec->requestQueueNotify();
}

int EmulatedCamera2::set_frame_queue_dst_ops(
    const camera2_device_t *d,
    const camera2_frame_queue_dst_ops *queue_dst_ops) {
  EmulatedCamera2 *ec = getInstance(d);
  ec->mFrameQueueDst = queue_dst_ops;
  return NO_ERROR;
}

int EmulatedCamera2::get_in_progress_count(const camera2_device_t *d) {
  EmulatedCamera2 *ec = getInstance(d);
  return ec->getInProgressCount();
}

int EmulatedCamera2::flush_captures_in_progress(const camera2_device_t *d) {
  EmulatedCamera2 *ec = getInstance(d);
  return ec->flushCapturesInProgress();
}

int EmulatedCamera2::construct_default_request(const camera2_device_t *d,
                                               int request_template,
                                               camera_metadata_t **request) {
  EmulatedCamera2 *ec = getInstance(d);
  return ec->constructDefaultRequest(request_template, request);
}

int EmulatedCamera2::allocate_stream(const camera2_device_t *d, uint32_t width,
                                     uint32_t height, int format,
                                     const camera2_stream_ops_t *stream_ops,
                                     uint32_t *stream_id,
                                     uint32_t *format_actual, uint32_t *usage,
                                     uint32_t *max_buffers) {
  EmulatedCamera2 *ec = getInstance(d);
  return ec->allocateStream(width, height, format, stream_ops, stream_id,
                            format_actual, usage, max_buffers);
}

int EmulatedCamera2::register_stream_buffers(const camera2_device_t *d,
                                             uint32_t stream_id,
                                             int num_buffers,
                                             buffer_handle_t *buffers) {
  EmulatedCamera2 *ec = getInstance(d);
  return ec->registerStreamBuffers(stream_id, num_buffers, buffers);
}
int EmulatedCamera2::release_stream(const camera2_device_t *d,
                                    uint32_t stream_id) {
  EmulatedCamera2 *ec = getInstance(d);
  return ec->releaseStream(stream_id);
}

int EmulatedCamera2::allocate_reprocess_stream(
    const camera2_device_t *d, uint32_t width, uint32_t height, uint32_t format,
    const camera2_stream_in_ops_t *reprocess_stream_ops, uint32_t *stream_id,
    uint32_t *consumer_usage, uint32_t *max_buffers) {
  EmulatedCamera2 *ec = getInstance(d);
  return ec->allocateReprocessStream(width, height, format,
                                     reprocess_stream_ops, stream_id,
                                     consumer_usage, max_buffers);
}

int EmulatedCamera2::allocate_reprocess_stream_from_stream(
    const camera2_device_t *d, uint32_t output_stream_id,
    const camera2_stream_in_ops_t *reprocess_stream_ops, uint32_t *stream_id) {
  EmulatedCamera2 *ec = getInstance(d);
  return ec->allocateReprocessStreamFromStream(output_stream_id,
                                               reprocess_stream_ops, stream_id);
}

int EmulatedCamera2::release_reprocess_stream(const camera2_device_t *d,
                                              uint32_t stream_id) {
  EmulatedCamera2 *ec = getInstance(d);
  return ec->releaseReprocessStream(stream_id);
}

int EmulatedCamera2::trigger_action(const camera2_device_t *d,
                                    uint32_t trigger_id, int ext1, int ext2) {
  EmulatedCamera2 *ec = getInstance(d);
  return ec->triggerAction(trigger_id, ext1, ext2);
}

int EmulatedCamera2::set_notify_callback(const camera2_device_t *d,
                                         camera2_notify_callback notify_cb,
                                         void *user) {
  EmulatedCamera2 *ec = getInstance(d);
  Mutex::Autolock l(ec->mMutex);
  ec->mNotifyCb = notify_cb;
  ec->mNotifyUserPtr = user;
  return NO_ERROR;
}

int EmulatedCamera2::get_instance_metadata(
    const struct camera2_device *d, camera_metadata **instance_metadata) {
  EmulatedCamera2 *ec = getInstance(d);
  if (!ec) {
    return INVALID_OPERATION;
  }
  *instance_metadata = ec->mCameraInfo;
  return NO_ERROR;
}

int EmulatedCamera2::get_metadata_vendor_tag_ops(const camera2_device_t *d,
                                                 vendor_tag_query_ops_t **ops) {
  EmulatedCamera2 *ec = getInstance(d);
  *ops = static_cast<vendor_tag_query_ops_t *>(&ec->mVendorTagOps);
  return NO_ERROR;
}

const char *EmulatedCamera2::get_camera_vendor_section_name(
    const vendor_tag_query_ops_t *v, uint32_t tag) {
  EmulatedCamera2 *ec = static_cast<const TagOps *>(v)->parent;
  return ec->getVendorSectionName(tag);
}

const char *EmulatedCamera2::get_camera_vendor_tag_name(
    const vendor_tag_query_ops_t *v, uint32_t tag) {
  EmulatedCamera2 *ec = static_cast<const TagOps *>(v)->parent;
  return ec->getVendorTagName(tag);
}

int EmulatedCamera2::get_camera_vendor_tag_type(const vendor_tag_query_ops_t *v,
                                                uint32_t tag) {
  EmulatedCamera2 *ec = static_cast<const TagOps *>(v)->parent;
  return ec->getVendorTagType(tag);
}

int EmulatedCamera2::dump(const camera2_device_t *d, int fd) {
  EmulatedCamera2 *ec = getInstance(d);
  return ec->dump(fd);
}

int EmulatedCamera2::close(struct hw_device_t *device) {
  EmulatedCamera2 *ec = static_cast<EmulatedCamera2 *>(
      reinterpret_cast<camera2_device_t *>(device));
  if (ec == NULL) {
    ALOGE("%s: Unexpected NULL camera2 device", __FUNCTION__);
    return -EINVAL;
  }
  return ec->closeCamera();
}

void EmulatedCamera2::sendNotification(int32_t msgType, int32_t ext1,
                                       int32_t ext2, int32_t ext3) {
  camera2_notify_callback notifyCb;
  {
    Mutex::Autolock l(mMutex);
    notifyCb = mNotifyCb;
  }
  if (notifyCb != NULL) {
    notifyCb(msgType, ext1, ext2, ext3, mNotifyUserPtr);
  }
}

camera2_device_ops_t EmulatedCamera2::sDeviceOps = {
    EmulatedCamera2::set_request_queue_src_ops,
    EmulatedCamera2::notify_request_queue_not_empty,
    EmulatedCamera2::set_frame_queue_dst_ops,
    EmulatedCamera2::get_in_progress_count,
    EmulatedCamera2::flush_captures_in_progress,
    EmulatedCamera2::construct_default_request,
    EmulatedCamera2::allocate_stream,
    EmulatedCamera2::register_stream_buffers,
    EmulatedCamera2::release_stream,
    EmulatedCamera2::allocate_reprocess_stream,
    EmulatedCamera2::allocate_reprocess_stream_from_stream,
    EmulatedCamera2::release_reprocess_stream,
    EmulatedCamera2::trigger_action,
    EmulatedCamera2::set_notify_callback,
    EmulatedCamera2::get_metadata_vendor_tag_ops,
    EmulatedCamera2::dump,
#ifdef CAMERA_DEVICE_API_VERSION_2_1
    EmulatedCamera2::get_instance_metadata,
#endif
};

}; /* namespace android */
