/*
 * 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 <fcntl.h>
#include <poll.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <unistd.h>

#include "cros-camera/common.h"

namespace cros {
V4L2Device::V4L2Device(const std::string name) : name_(name), fd_(-1) {}

V4L2Device::~V4L2Device() {
  VLOGF_ENTER();
  if (IsOpened()) {
    LOGF(WARNING) << "Destroying a device object not closed, closing first";
    Close();
  }
}

int V4L2Device::Open(int flags) {
  VLOGF_ENTER();
  if (IsOpened()) {
    LOGF(WARNING) << "Device is already opened";
    return 0;
  }

  struct stat st = {};
  if (stat(name_.c_str(), &st) == -1) {
    PLOGF(ERROR) << "Error stat video device " << name_.c_str();
    return -ENODEV;
  }
  if (!S_ISCHR(st.st_mode)) {
    LOGF(ERROR) << name_.c_str() << " is not a device";
    return -ENODEV;
  }

  fd_ = ::open(name_.c_str(), flags);
  if (fd_ < 0) {
    PLOGF(ERROR) << "Error opening video device " << name_.c_str();
    return -errno;
  }
  return 0;
}

int V4L2Device::Close() {
  VLOGF_ENTER();

  if (!IsOpened()) {
    LOGF(WARNING) << "Device is not opened!";
    return -EINVAL;
  }

  int ret = ::close(fd_);
  if (ret < 0) {
    PLOGF(ERROR) << "Error closing video device " << name_.c_str();
    return ret;
  }

  fd_ = -1;
  return 0;
}

int V4L2Device::SubscribeEvent(int event) {
  VLOGF_ENTER();
  if (!IsOpened()) {
    LOGF(ERROR) << "Device " << name_ << " already closed. Do nothing.";
    return -1;
  }

  struct v4l2_event_subscription sub = {};
  sub.type = event;
  int ret = ::ioctl(fd_, VIDIOC_SUBSCRIBE_EVENT, &sub);
  if (ret < 0) {
    PLOGF(ERROR) << "Error subscribing event 0x" << std::hex << event;
    return ret;
  }

  return ret;
}

int V4L2Device::UnsubscribeEvent(int event) {
  VLOGF_ENTER();

  if (!IsOpened()) {
    LOGF(ERROR) << "Device " << name_ << " already closed. Do nothing.";
    return -1;
  }

  struct v4l2_event_subscription sub = {};
  sub.type = event;

  int ret = ::ioctl(fd_, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
  if (ret < 0) {
    PLOGF(ERROR) << "Error unsubscribing event 0x" << std::hex << event;
    return ret;
  }

  return ret;
}

int V4L2Device::DequeueEvent(struct v4l2_event* event) {
  VLOGF_ENTER();
  if (!event) {
    return -EINVAL;
  }

  if (!IsOpened()) {
    LOGF(ERROR) << "Device " << name_ << " already closed. Do nothing.";
    return -1;
  }

  int ret = ::ioctl(fd_, VIDIOC_DQEVENT, event);
  if (ret < 0) {
    LOGF(ERROR) << "error dequeuing event";
    return ret;
  }

  return ret;
}

int V4L2Device::SetControl(struct v4l2_control* control) {
  if (!IsOpened()) {
    LOGF(ERROR) << "Invalid device state (CLOSED)";
    return -EINVAL;
  }
  if (!control) {
    LOGF(ERROR) << "Null pointer of control";
    return -EINVAL;
  }
  return ::ioctl(fd_, VIDIOC_S_CTRL, control);
}

int V4L2Device::SetControl(struct v4l2_ext_control* ext_control) {
  if (!IsOpened()) {
    LOGF(ERROR) << "Invalid device state (CLOSED)";
    return -EINVAL;
  }
  if (!ext_control) {
    LOGF(ERROR) << "Null pointer of ext_control";
    return -EINVAL;
  }
  struct v4l2_ext_controls controls = {};
  controls.ctrl_class = V4L2_CTRL_ID2CLASS(ext_control->id);
  controls.count = 1;
  controls.controls = ext_control;
  return ::ioctl(fd_, VIDIOC_S_EXT_CTRLS, &controls);
}

int V4L2Device::SetControl(int id, int32_t value) {
  VLOGF_ENTER();
  VLOGF(2) << "Setting attribute " << id << " to " << value;
  int ret = 0;

  struct v4l2_ext_control ext_control = {};
  ext_control.id = id;
  ext_control.value = value;
  ret = SetControl(&ext_control);
  if (ret != 0) {
    PLOGF(ERROR) << "Failed to set value " << value << " for control " << id
                 << " on device " << name_.c_str();
  }
  return ret;
}

int V4L2Device::SetControl(int id, int64_t value) {
  VLOGF_ENTER();
  VLOGF(2) << "Setting attribute " << id << " to " << value;
  struct v4l2_ext_control ext_control = {};
  ext_control.id = id;
  ext_control.value64 = value;
  int ret = SetControl(&ext_control);
  if (ret != 0) {
    PLOGF(ERROR) << "Failed to set value " << value << " for control " << id
                 << " on device " << name_.c_str();
  }
  return ret;
}

int V4L2Device::SetControl(int id, const std::string value) {
  VLOGF_ENTER();
  VLOGF(2) << "Setting attribute " << id << " to " << value;
  struct v4l2_ext_control ext_control = {};
  ext_control.id = id;
  ext_control.string = const_cast<char*>(value.c_str());
  int ret = SetControl(&ext_control);
  if (ret != 0) {
    PLOGF(ERROR) << "Failed to set value " << value << " for control " << id
                 << " on device " << name_.c_str();
  }
  return ret;
}

int V4L2Device::GetControl(struct v4l2_ext_control* ext_control) {
  if (!IsOpened()) {
    LOGF(ERROR) << "Invalid state device (CLOSED)";
    return -EINVAL;
  }
  struct v4l2_ext_controls controls = {};
  controls.ctrl_class = V4L2_CTRL_ID2CLASS(ext_control->id);
  controls.count = 1;
  controls.controls = ext_control;

  int ret = ::ioctl(fd_, VIDIOC_G_EXT_CTRLS, &controls);
  if (ret != 0) {
    PLOGF(ERROR) << "Failed to get value for control (" << ext_control->id
                 << ") on device " << name_.c_str();
    return ret;
  }
  return 0;
}

int V4L2Device::GetControl(int id, int32_t* value) {
  VLOGF_ENTER();
  if (!value) {
    return -EINVAL;
  }
  struct v4l2_ext_control ext_control = {};
  ext_control.id = id;
  int ret = GetControl(&ext_control);
  if (ret == 0) {
    *value = ext_control.value;
  }
  return ret;
}

int V4L2Device::GetControl(int id, int64_t* value) {
  VLOGF_ENTER();
  if (!value) {
    return -EINVAL;
  }
  struct v4l2_ext_control ext_control = {};
  ext_control.id = id;
  int ret = GetControl(&ext_control);
  if (ret == 0) {
    *value = ext_control.value64;
  }
  return ret;
}

int V4L2Device::GetControl(int id, std::string* value) {
  VLOGF_ENTER();
  if (!value) {
    return -EINVAL;
  }
  struct v4l2_ext_control ext_control = {};
  ext_control.id = id;
  int ret = GetControl(&ext_control);
  if (ret == 0) {
    *value = ext_control.string;
  }
  return ret;
}

int V4L2Device::QueryMenu(v4l2_querymenu* menu) {
  VLOGF_ENTER();
  if (!menu) {
    return -EINVAL;
  }

  if (fd_ == -1) {
    LOGF(ERROR) << "Invalid state device (CLOSED)";
    return -EINVAL;
  }

  int ret = ::ioctl(fd_, VIDIOC_QUERYMENU, menu);
  if (ret != 0) {
    PLOGF(ERROR) << "Failed to get values for query menu (" << menu->id
                 << ") on device" << name_.c_str();
  }
  return ret;
}

int V4L2Device::QueryControl(v4l2_queryctrl* control) {
  VLOGF_ENTER();
  if (!control) {
    return -EINVAL;
  }

  if (fd_ == -1) {
    LOGF(ERROR) << "Invalid state device (CLOSED)";
    return -EINVAL;
  }

  int ret = ::ioctl(fd_, VIDIOC_QUERYCTRL, control);
  if (ret != 0) {
    PLOGF(ERROR) << "Failed to get values for query control (" << control->id
                 << ") on device " << name_.c_str();
  }
  return ret;
}

int V4L2Device::Poll(int timeout) {
  VLOGF_ENTER();
  struct pollfd pfd = {0};
  int ret(0);

  if (fd_ == -1) {
    LOGF(ERROR) << "Device " << name_.c_str() << " already closed. Do nothing.";
    return -1;
  }

  pfd.fd = fd_;
  pfd.events = POLLPRI | POLLIN | POLLERR;

  ret = ::poll(&pfd, 1, timeout);

  if (ret < 0) {
    LOGF(ERROR) << "poll error ret=" << ret << ", mFd= " << fd_
                << ", error:" << strerror(errno);
    return ret;
  }

  if (pfd.revents & POLLERR) {
    LOGF(ERROR) << "received POLLERR";
    return -1;
  }

  return ret;
}

V4L2DevicePoller::V4L2DevicePoller(std::vector<V4L2Device*> devices,
                                   int flush_fd)
    : devices_(std::move(devices)),
      flush_fd_(flush_fd),
      poll_fds_(devices_.size() + ((flush_fd == -1) ? 0 : 1)) {
  for (size_t i = 0; i < devices_.size(); i++) {
    if (!devices_[i]) {
      LOGF(ERROR) << "Invalid device at index " << i;
      poll_fds_.resize(0);
      return;
    }
    poll_fds_[i].fd = devices_[i]->fd_;
    poll_fds_[i].revents = 0;
  }
  if (flush_fd_ != -1) {
    poll_fds_.back().fd = flush_fd_;
    poll_fds_.back().events = POLLIN | POLLPRI;
  }
}

int V4L2DevicePoller::Poll(int timeout_ms,
                           int events,
                           std::vector<V4L2Device*>* ready_devices) {
  VLOGF_ENTER();
  if (poll_fds_.empty()) {
    return -EINVAL;
  }
  for (size_t i = 0; i < devices_.size(); i++) {
    poll_fds_[i].events = events;
  }
  int ret = ::poll(poll_fds_.data(), poll_fds_.size(), timeout_ms);
  if (ret <= 0) {
    for (size_t i = 0; i < devices_.size(); i++) {
      PLOGF(ERROR) << "Device " << devices_[i]->name_ << " poll failed ("
                   << ((ret == 0) ? "timeout)" : "error)");
    }
    return ret;
  }

  // check first the flush
  if (flush_fd_ != -1 && (poll_fds_.back().revents & (POLLIN | POLLPRI))) {
    VLOGF(1) << "Poll returning from flush";
    return ret;
  }

  bool is_pollerr = false;
  for (size_t i = 0; i < devices_.size(); i++) {
    if (poll_fds_[i].revents & POLLERR) {
      LOGF(ERROR) << "Device " << devices_[i]->name_ << " received POLLERR";
      is_pollerr = true;
    }
  }
  if (is_pollerr) {
    return -1;
  }

  if (ready_devices != nullptr) {
    // check other active devices.
    for (size_t i = 0; i < devices_.size(); i++) {
      // return nodes that have data available
      if (poll_fds_[i].revents & events) {
        ready_devices->push_back(devices_[i]);
      }
    }
  }
  return ret;
}
}  // namespace cros
