/*
 * Copyright (C) 2013-2017 Intel Corporation
 *
 * 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.
 */

// Copyright 2018 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 "cros-camera/v4l2_device.h"

#include <sys/ioctl.h>

#include "cros-camera/common.h"

namespace cros {

V4L2Subdevice::V4L2Subdevice(const std::string name)
    : V4L2Device(name), state_(SubdevState::CLOSED) {
  VLOGF_ENTER();
}

V4L2Subdevice::~V4L2Subdevice() {
  VLOGF_ENTER();
  {
    base::AutoLock l(state_lock_);
    if (state_ == SubdevState::CLOSED) {
      return;
    }
  }
  Close();
}

int V4L2Subdevice::Open(int flags) {
  VLOGF_ENTER();
  base::AutoLock l(state_lock_);
  int status = V4L2Device::Open(flags);
  if (status == 0)
    state_ = SubdevState::OPEN;
  return status;
}

int V4L2Subdevice::Close() {
  VLOGF_ENTER();
  base::AutoLock l(state_lock_);
  int status = V4L2Device::Close();
  state_ = (status == 0) ? SubdevState::CLOSED : SubdevState::ERROR;
  return status;
}

int V4L2Subdevice::SetFormat(const struct v4l2_subdev_format& format) {
  VLOGF_ENTER();
  base::AutoLock l(state_lock_);
  if ((state_ != SubdevState::OPEN) && (state_ != SubdevState::CONFIGURED)) {
    LOGF(ERROR) << "Invalid device state " << static_cast<int>(state_);
    return -EINVAL;
  }

  VLOGF(1) << "VIDIOC_SUBDEV_S_FMT:"
           << "    pad:" << format.pad << "    which:" << format.which
           << "    width:" << format.format.width
           << "    height:" << format.format.height << "    format:0x"
           << std::hex << format.format.code << "    field:" << std::dec
           << format.format.field
           << "    color space:" << format.format.colorspace;

  int ret = ::ioctl(fd_, VIDIOC_SUBDEV_S_FMT, &format);
  if (ret < 0) {
    PLOGF(ERROR) << "VIDIOC_SUBDEV_S_FMT failed";
    return -EINVAL;
  }

  VLOGF(2) << "VIDIOC_SUBDEV_S_FMT:"
           << "    pad:" << format.pad << "    which:" << format.which
           << "    width:" << format.format.width
           << "    height:" << format.format.height << "    format:0x"
           << std::hex << format.format.code << "    field:" << std::dec
           << format.format.field
           << "    color space:" << format.format.colorspace;

  state_ = SubdevState::CONFIGURED;
  return 0;
}

int V4L2Subdevice::GetFormat(struct v4l2_subdev_format* format) {
  VLOGF_ENTER();
  base::AutoLock l(state_lock_);
  if ((state_ != SubdevState::OPEN) && (state_ != SubdevState::CONFIGURED)) {
    LOGF(ERROR) << "Invalid device state " << static_cast<int>(state_);
    return -EINVAL;
  }

  int ret = ::ioctl(fd_, VIDIOC_SUBDEV_G_FMT, format);
  if (ret < 0) {
    PLOGF(ERROR) << "VIDIOC_SUBDEV_G_FMT failed";
    return -EINVAL;
  }

  VLOGF(1) << "VIDIOC_SUBDEV_G_FMT:"
           << "    pad:" << format->pad << "    which:" << format->which
           << "    width:" << format->format.width
           << "    height:" << format->format.height << "    format:0x"
           << std::hex << format->format.code << "    field:" << std::dec
           << format->format.field
           << "    color space:" << format->format.colorspace;

  return 0;
}

int V4L2Subdevice::GetPadFormat(int pad_index,
                                int* width,
                                int* height,
                                int* code) {
  VLOGF_ENTER();
  if (!width || !height || !code) {
    return -EINVAL;
  }
  struct v4l2_subdev_format format = {};

  format.pad = pad_index;
  format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
  int ret = GetFormat(&format);
  if (ret == 0) {
    *width = format.format.width;
    *height = format.format.height;
    *code = format.format.code;
  }
  return ret;
}

int V4L2Subdevice::SetSelection(const struct v4l2_subdev_selection& selection) {
  VLOGF_ENTER();
  base::AutoLock l(state_lock_);
  if ((state_ != SubdevState::OPEN) && (state_ != SubdevState::CONFIGURED)) {
    LOGF(ERROR) << "Invalid device state " << static_cast<int>(state_);
    return -EINVAL;
  }

  VLOGF(1) << "VIDIOC_SUBDEV_S_SELECTION:"
           << "    which:" << selection.which << "    pad:" << selection.pad
           << "    target:" << std::hex << selection.target
           << "    flags:" << selection.flags << "    left:" << std::dec
           << selection.r.left << "    top:" << selection.r.top
           << "    width:" << selection.r.width
           << "    height:" << selection.r.height;

  int ret = ::ioctl(fd_, VIDIOC_SUBDEV_S_SELECTION, &selection);
  if (ret < 0) {
    PLOGF(ERROR) << "VIDIOC_SUBDEV_S_SELECTION failed";
  }
  return ret;
}

}  // namespace cros
