/*
 * 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.

#ifndef CAMERA_INCLUDE_CROS_CAMERA_V4L2_DEVICE_H_
#define CAMERA_INCLUDE_CROS_CAMERA_V4L2_DEVICE_H_

#include <linux/v4l2-subdev.h>
#include <linux/videodev2.h>
#include <poll.h>

#include <atomic>
#include <string>
#include <vector>

#include <base/synchronization/lock.h>

#include "cros-camera/export.h"

namespace cros {

/*
 * Wrapper for v4l2_buffer to provide compatible
 * interfaces for multi-plane buffers.
 */
class CROS_CAMERA_EXPORT V4L2Buffer {
 public:
  V4L2Buffer();
  explicit V4L2Buffer(const V4L2Buffer& buf);
  uint32_t Index() const { return v4l2_buf_.index; }
  void SetIndex(uint32_t index) { v4l2_buf_.index = index; }
  uint32_t Type() const { return v4l2_buf_.type; }
  void SetType(uint32_t type);
  uint32_t Flags() const { return v4l2_buf_.flags; }
  void SetFlags(uint32_t flags) { v4l2_buf_.flags = flags; }
  uint32_t Field() const { return v4l2_buf_.field; }
  void SetField(uint32_t field) { v4l2_buf_.field = field; }
  struct timeval Timestamp() const {
    return v4l2_buf_.timestamp;
  }
  void SetTimestamp(struct timeval timestamp) {
    v4l2_buf_.timestamp = timestamp;
  }
  struct v4l2_timecode Timecode() const {
    return v4l2_buf_.timecode;
  }
  void SetTimecode(struct v4l2_timecode timecode) {
    v4l2_buf_.timecode = timecode;
  }
  uint32_t Sequence() const { return v4l2_buf_.sequence; }
  void SetSequence(uint32_t sequence) { v4l2_buf_.sequence = sequence; }
  uint32_t Memory() const { return v4l2_buf_.memory; }
  void SetMemory(uint32_t memory) { v4l2_buf_.memory = memory; }
  uint32_t Offset(uint32_t plane) const;
  void SetOffset(uint32_t offset, uint32_t plane);
  uintptr_t Userptr(uint32_t plane) const;
  void SetUserptr(uintptr_t userptr, uint32_t plane);
  int Fd(uint32_t plane) const;
  void SetFd(int fd, uint32_t plane);
  uint32_t BytesUsed(uint32_t plane) const;
  void SetBytesUsed(uint32_t bytesused, uint32_t plane);
  uint32_t Length(uint32_t plane) const;
  void SetLength(uint32_t length, uint32_t plane);
  const struct v4l2_buffer* Get() const { return &v4l2_buf_; }
  const V4L2Buffer& operator=(const V4L2Buffer& buf);

 private:
  struct v4l2_buffer v4l2_buf_;
  std::vector<struct v4l2_plane> planes_;  // For multi-planar buffers.
};

/*
 * Wrapper for v4l2_format to provide compatible
 * interfaces for multi-plane buffers.
 */
class CROS_CAMERA_EXPORT V4L2Format {
 public:
  V4L2Format() { v4l2_fmt_ = {}; }
  explicit V4L2Format(const struct v4l2_format& fmt) { v4l2_fmt_ = fmt; }
  const V4L2Format& operator=(const V4L2Format& fmt);
  uint32_t Type() const { return v4l2_fmt_.type; }
  void SetType(uint32_t type);
  uint32_t Width() const;
  void SetWidth(uint32_t width);
  uint32_t Height() const;
  void SetHeight(uint32_t height);
  uint32_t PixelFormat() const;
  void SetPixelFormat(uint32_t format);
  uint32_t Field() const;
  void SetField(uint32_t field);
  uint32_t BytesPerLine(uint32_t plane) const;
  void SetBytesPerLine(uint32_t bytesperline, uint32_t plane);
  uint32_t SizeImage(uint32_t plane) const;
  void SetSizeImage(uint32_t size, uint32_t plane);
  struct v4l2_format* Get() {
    return &v4l2_fmt_;
  }

 private:
  struct v4l2_format v4l2_fmt_;
};

/**
 * A class encapsulating simple V4L2 device operations.
 *
 * Base class that contains common V4L2 operations used by video nodes and
 * subdevices. It provides a slightly higher interface than IOCTLS to access
 * the devices. It also stores:
 * - Name
 * - File descriptor
 */
class CROS_CAMERA_EXPORT V4L2Device {
 public:
  friend class V4L2DevicePoller;

  explicit V4L2Device(const std::string name);

  virtual ~V4L2Device();

  // This method opens the V4L2 device.
  //
  // Args:
  //    |flags|: open flags, e.g. O_RDWR, O_NONBLOCK.
  //
  // Returns:
  //    0 on success; corresponding error code on failure.
  virtual int Open(int flags);

  // This method closes the V4L2 device.
  //
  // Returns:
  //    0 on success; corresponding error code on failure.
  virtual int Close();

  // These methods sets the control of V4L2 device.
  //
  // Args:
  //    |id|: control identifier.
  //    |value|: new value.
  //
  // Returns:
  //    0 on success; corresponding error code on failure.
  int SetControl(int id, int32_t value);
  int SetControl(int id, int64_t value);
  int SetControl(int id, const std::string value);

  // These methods gets the control of V4L2 device.
  //
  // Args:
  //    |id|: control identifier.
  //    |value|: current value.
  //
  // Returns:
  //    0 on success; corresponding error code on failure.
  int GetControl(int id, int32_t* value);
  int GetControl(int id, int64_t* value);
  int GetControl(int id, std::string* value);

  // This method enumerates the menu control items of V4L2 device.
  //
  // Args:
  //    |menu|: menu control.
  //
  // Returns:
  //    0 on success; corresponding error code on failure.
  int QueryMenu(v4l2_querymenu* menu);

  // This method enumerates the control of V4L2 device.
  //
  // Args:
  //    |control|: control.
  //
  // Returns:
  //    0 on success; corresponding error code on failure.
  int QueryControl(v4l2_queryctrl* control);

  // This method subscribes event of V4L2 device.
  //
  // Args:
  //    |event|: event type.
  //
  // Returns:
  //    0 on success; corresponding error code on failure.
  int SubscribeEvent(int event);

  // This method unsubscribes event of V4L2 device.
  //
  // Args:
  //    |event|: event type.
  //
  // Returns:
  //    0 on success; corresponding error code on failure.
  int UnsubscribeEvent(int event);

  // This method dequeues event of V4L2 device.
  //
  // Args:
  //    |event|: V4L2 event.
  //
  // Returns:
  //    0 on success; corresponding error code on failure.
  int DequeueEvent(struct v4l2_event* event);

  // This method checks whether V4L2 device is opened.
  //
  // Returns:
  //    True if it is opened.
  bool IsOpened() { return fd_ != -1; }

  // This method gets the name of V4L2 device.
  //
  // Returns:
  //    Device name.
  const std::string Name() { return name_; }

 private:
  int SetControl(struct v4l2_ext_control* ext_control);

  int GetControl(struct v4l2_ext_control* ext_control);

 protected:
  std::string name_; /*!< path to device in file system, ex: /dev/video0 */

  int fd_; /*!< file descriptor obtained when device is open */
};

class CROS_CAMERA_EXPORT V4L2DevicePoller {
 public:
  // |flush_fd|: file descriptor of the pipe device that will be used to return
  // from Poll() in case of flush request, i.e., to abort poll before timeout
  explicit V4L2DevicePoller(std::vector<V4L2Device*> devices, int flush_fd);

  virtual ~V4L2DevicePoller() {}

  // This method polls the V4L2 device.
  //
  // Args:
  //    |timeout_ms|: the number of milliseconds that Poll() should block
  //      waiting for devices to become ready.
  //    |events|: a bit mask specifying the events the client is
  //      interested in.
  //    |ready_devices|: devices that become ready
  //
  // Returns:
  //    On success, a positive number is returned; this is the number of
  //    devices which have the specified events occurred. A value of 0
  //    indicates that the call timed out and no file descriptors were ready.
  //    On error, -1 is returned.
  int Poll(int timeout_ms, int events, std::vector<V4L2Device*>* ready_devices);

 private:
  std::vector<V4L2Device*> devices_;

  int flush_fd_;

  std::vector<struct pollfd> poll_fds_;
};

/**
 * A class encapsulating simple V4L2 video device node operations.
 *
 * This class extends V4L2Device and adds extra internal state
 * and more convenience methods to manage an associated buffer pool
 * with the device.
 * This class introduces new methods specific to control video device nodes.
 */
class CROS_CAMERA_EXPORT V4L2VideoNode final : public V4L2Device {
 public:
  explicit V4L2VideoNode(const std::string name);

  ~V4L2VideoNode();

  // This method opens the video device.
  //
  // Args:
  //    |flags|: open flags, e.g. O_RDWR, O_NONBLOCK.
  //
  // Returns:
  //    0 on success; corresponding error code on failure.
  int Open(int flags) final;

  // This method closes the video device.
  //
  // Returns:
  //    0 on success; corresponding error code on failure.
  int Close() final;

  // This method gets the data format of video device.
  //
  // Args:
  //    |format|: V4L2 format returned.
  //
  // Returns:
  //    0 on success; corresponding error code on failure.
  int GetFormat(V4L2Format* format);

  // This method configures the data format of video device.
  //
  // Args:
  //    |format|: V4L2 format.
  //
  // Returns:
  //    0 on success; corresponding error code on failure.
  int SetFormat(const V4L2Format& format);

  // This method configures the selection rectangles of video device.
  //
  // Args:
  //    |selection|: V4L2 selection rectangle.
  //
  // Returns:
  //    0 on success; corresponding error code on failure.
  int SetSelection(const struct v4l2_selection& selection);

  // This method get the memory type of video device.
  //
  // Returns:
  //    V4L2 memory type.
  enum v4l2_memory GetMemoryType();

  // This method maps video device buffers into memory.
  //
  // Args:
  //    |index|: number of the buffer.
  //    |prot|: desired memory protection of the mapping.
  //    |flags|: mapping flags.
  //    |mapped|: mapped addresses.
  //
  // Returns:
  //    A pointer to the mapped area; MAP_FAILED on failure.
  int MapMemory(unsigned int index,
                int prot,
                int flags,
                std::vector<void*>* mapped);

  // This method sets up buffers of the video device. If USERPTR memory type is
  // specified, the caller may need to fill in the userptr field of returned
  // buffers.
  //
  // Args:
  //    |num_buffers|: number of buffers to set up
  //    |is_cached|: whether the buffers are cached or not
  //    |memory_type_|: memory type of buffers
  //    |buffers|: buffers returned
  //
  // Returns:
  //    0 on success; corresponding error code on failure.
  int SetupBuffers(size_t num_buffers,
                   bool is_cached,
                   enum v4l2_memory memory_type,
                   std::vector<V4L2Buffer>* buffers);

  // This method stops streaming of the video device.
  //
  // Returns:
  //    0 on success; corresponding error code on failure.
  int Stop();

  // This method starts streaming of the video device.
  //
  // Returns:
  //    0 on success; corresponding error code on failure.
  int Start();

  // This method grabs a buffer from the video device's outgoing queue.
  //
  // Args:
  //    |buf|: V4L2 buffer.
  //
  // Returns:
  //    0 on success; corresponding error code on failure.
  int GrabFrame(V4L2Buffer* buf);

  // This method enqueues a buffer in the video device's outgoing queue.
  //
  // Args:
  //    |buf|: V4L2 buffer.
  //
  // Returns:
  //    0 on success; corresponding error code on failure.
  int PutFrame(V4L2Buffer* buf);

  // This method exports a buffer as DMABUF file descriptors.
  //
  // Args:
  //    |index|: number of the buffer.
  //    |fds|: exported file descriptors.
  //
  // Returns:
  //    0 on success; corresponding error code on failure.
  int ExportFrame(unsigned int index, std::vector<int>* fds);

 private:
  // This method queries the capabilities of the video device.
  //
  // Args:
  //    |cap|: V4L2 capabilities
  //
  // Returns:
  //    0 on success; corresponding error code on failure.
  int QueryCap(struct v4l2_capability* cap);

  int Qbuf(V4L2Buffer* buf);

  int Dqbuf(V4L2Buffer* buf);

  int QueryBuffer(int index, enum v4l2_memory memory_type, V4L2Buffer* buf);

  int RequestBuffers(size_t num_buffers, enum v4l2_memory memory_type);

  int StopLocked();

  void DestroyBufferPool();

  void PrintBufferInfo(const std::string func, const V4L2Buffer& buf);

  enum class VideoNodeState {
    CLOSED = 0, /*!< kernel device closed */
    OPEN,       /*!< device node opened */
    CONFIGURED, /*!< device format set, IOC_S_FMT */
    PREPARED,   /*!< device has requested buffers (set_buffer_pool)*/
    STARTED,    /*!< stream started, IOC_STREAMON */
    ERROR       /*!< undefined state */
  };

  // Lock to protect |state_|
  base::Lock state_lock_;

  VideoNodeState state_;

  // Device capture configuration
  V4L2Format format_;

  bool is_buffer_cached_;

  enum v4l2_buf_type buffer_type_;

  enum v4l2_memory memory_type_;
};

/**
 * A class encapsulating simple V4L2 sub device node operations.
 *
 * Sub-devices are control points to the new V4L2 media controller
 * architecture.
 */
class CROS_CAMERA_EXPORT V4L2Subdevice final : public V4L2Device {
 public:
  explicit V4L2Subdevice(const std::string name);

  ~V4L2Subdevice();

  // This method opens the sub-device.
  //
  // Args:
  //    |flags|: open flags, e.g. O_RDWR, O_NONBLOCK.
  //
  // Returns:
  //    0 on success; corresponding error code on failure.
  int Open(int flags) final;

  // This method closes the sub-device.
  //
  // Returns:
  //    0 on success; corresponding error code on failure.
  int Close() final;

  // This method configures format of the sub-device.
  //
  // Args:
  //    |format|: V4L2 sub-device format.
  //
  // Returns:
  //    0 on success; corresponding error code on failure.
  int SetFormat(const struct v4l2_subdev_format& format);

  // This method configures the selection rectangles of sub-device pad.
  //
  // Args:
  //    |selection|: V4L2 sub-device selection rectangle.
  //
  // Returns:
  //    0 on success; corresponding error code on failure.
  int SetSelection(const struct v4l2_subdev_selection& selection);

  // This method gets the format of sub-device pad.
  //
  // Args:
  //    |pad_index|: pad number.
  //    |width|: image width.
  //    |height|: image height.
  //    |code|: format code.
  //
  // Returns:
  //    0 on success; corresponding error code on failure.
  int GetPadFormat(int pad_index, int* width, int* height, int* code);

 private:
  int GetFormat(struct v4l2_subdev_format* format);

 private:
  enum class SubdevState {
    CLOSED = 0, /*!< kernel device closed */
    OPEN,       /*!< device node opened */
    CONFIGURED, /*!< device format set, IOC_S_FMT */
    ERROR       /*!< undefined state */
  };

  // Lock to protect |state_|
  base::Lock state_lock_;

  SubdevState state_;
};

}  // namespace cros
#endif  // CAMERA_INCLUDE_CROS_CAMERA_V4L2_DEVICE_H_
