/*
 * Copyright 2020 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_DEVICE_CONFIG_H_
#define CAMERA_INCLUDE_CROS_CAMERA_DEVICE_CONFIG_H_

#include <linux/media.h>

#include <memory>
#include <string>
#include <vector>

#include <base/optional.h>
#include <base/containers/span.h>
#include <base/files/file_path.h>
#include <base/strings/stringprintf.h>

#include "cros-camera/export.h"

namespace cros {

// The physical transmission interface, or bus, of a camera.
enum class Interface {
  kUsb,
  kMipi,
};

// The direction a camera faces. The definition should match
// camera_metadata_enum_android_lens_facing_t in camera_metadata_tags.h.
enum class LensFacing {
  kFront,
  kBack,
  kExternal,
};

struct EepromIdBlock {
  char os[4];
  uint16_t crc;
  uint8_t version;
  uint8_t length;
  uint16_t data_format;
  uint16_t module_pid;
  char module_vid[2];
  char sensor_vid[2];
  uint16_t sensor_pid;
};

struct EepromInfo {
  EepromIdBlock id_block;
  base::FilePath nvmem_path;
};

struct V4L2SensorInfo {
  std::string name;
  std::string vendor_id;
  base::FilePath subdev_path;
};

struct CrosConfigCameraInfo {
  Interface interface;
  LensFacing facing;
  int orientation;
};

struct PlatformCameraInfo {
  base::Optional<EepromInfo> eeprom;
  base::Optional<V4L2SensorInfo> v4l2_sensor;
  std::string sysfs_name;

  std::string module_id() const {
    if (!eeprom.has_value()) {
      return "";
    }
    return base::StringPrintf("%c%c%04x", eeprom->id_block.module_vid[0],
                              eeprom->id_block.module_vid[1],
                              eeprom->id_block.module_pid);
  }

  std::string sensor_id() const {
    if (!eeprom.has_value()) {
      return "";
    }
    return base::StringPrintf("%c%c%04x", eeprom->id_block.sensor_vid[0],
                              eeprom->id_block.sensor_vid[1],
                              eeprom->id_block.sensor_pid);
  }
};

// This class wraps the brillo::CrosConfig and stores the required values.
class CROS_CAMERA_EXPORT DeviceConfig {
 public:
  static base::Optional<DeviceConfig> Create();

  bool IsV1Device() const { return is_v1_device_; }

  // Gets the model name of the device.
  const std::string& GetModelName() const { return model_name_; }

  // Gets the total number of built-in cameras on the device, or nullopt if the
  // information is not available.
  base::Optional<int> GetBuiltInCameraCount() const { return count_; }

  // Gets the total number of cameras on the given interface |interface|, or
  // nullopt if the information is not available.
  base::Optional<int> GetCameraCount(Interface interface) const;

  // Gets camera orientation of the camera facing the given |facing| direction,
  // or nullopt if the information is not available.
  base::Optional<int> GetOrientationFromFacing(LensFacing facing) const;

  base::span<const PlatformCameraInfo> GetPlatformCameraInfo() const {
    return platform_cameras_;
  }

 private:
  DeviceConfig() = default;

  void ProbeSensorSubdev(struct media_entity_desc* desc,
                         const base::FilePath& path);
  base::FilePath FindSubdevSysfsByDevId(int major, int minor);
  void ProbeMediaController(int media_fd);
  void AddV4L2Sensors();
  void AddCameraEeproms();

  static bool PopulateCrosConfigCameraInfo(DeviceConfig* dev_conf);
  static void PopulatePlatformCameraInfo(DeviceConfig* dev_conf);

  bool is_v1_device_;
  std::string model_name_;

  // The number of built-in cameras, or |base::nullopt| when this information is
  // not available.
  base::Optional<int> count_;

  // Detailed topology of the camera devices, or empty when this information is
  // not available. |count_| has value |devices_.size()| if |devices_| is not
  // empty.
  std::vector<CrosConfigCameraInfo> cros_config_cameras_;

  std::vector<PlatformCameraInfo> platform_cameras_;
  std::vector<EepromInfo> eeproms_;
  std::vector<V4L2SensorInfo> v4l2_sensors_;
};

}  // namespace cros

#endif  // CAMERA_INCLUDE_CROS_CAMERA_DEVICE_CONFIG_H_
