/*
 * Copyright 2016 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 "hal/usb/camera_characteristics.h"

#include <fstream>
#include <map>
#include <set>
#include <sstream>
#include <utility>
#include <vector>

#include <base/files/file_util.h>
#include <base/strings/string_split.h>
#include <base/strings/string_util.h>
#include <re2/re2.h>

#include "cros-camera/common.h"
#include "cros-camera/timezone.h"
#include "hal/usb/quirks.h"

namespace cros {

// TODO(shik): Should we replace the custom format by proto/json/yaml/toml/xml?

namespace {

bool IsUsbV1Key(const std::string& key) {
  static const std::set<std::string> kV1Keys = {
      "horizontal_view_angle_16_9",      "horizontal_view_angle_4_3",
      "vertical_view_angle_16_9",        "vertical_view_angle_4_3",
      "resolution_1280x960_unsupported", "resolution_1600x1200_unsupported",
      "allow_external_camera",
  };
  return kV1Keys.count(key);
}

template <typename T>
void ParseSize(const std::string& value, T* width, T* height) {
  CHECK(RE2::FullMatch(value, "(.*)x(.*)", width, height));
}

template <typename T>
std::vector<T> ParseCommaSeparated(const std::string& value) {
  std::vector<std::string> values = base::SplitString(
      value, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
  size_t n = values.size();
  std::vector<T> res(n);
  for (size_t i = 0; i < n; i++) {
    CHECK(std::istringstream(values[i]) >> res[i])
        << "Failed to parse " << values[i];
  }
  return res;
}

uint32_t ParseQuirks(const std::string& value) {
  static const std::map<std::string, uint32_t> kNameMap = {
      {"monocle", kQuirkMonocle},
      {"prefer_mjpeg", kQuirkPreferMjpeg},
  };
  std::vector<std::string> names = base::SplitString(
      value, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
  uint32_t quirks = 0;
  for (const auto& name : names) {
    auto it = kNameMap.find(name);
    CHECK(it != kNameMap.end()) << "Invalid quirk name " << name;
    quirks |= it->second;
  }
  return quirks;
}

void SetEntry(const std::string& key,
              const std::string& value,
              DeviceInfo* info) {
  // Follow the same order as defined in common_types.h
  if (key == "usb_vid_pid") {
    CHECK(RE2::FullMatch(value, "([0-9a-f]{4}):([0-9a-f]{4})", &info->usb_vid,
                         &info->usb_pid));
  } else if (key == "frames_to_skip_after_streamon") {
    info->frames_to_skip_after_streamon = stoi(value);
  } else if (key == "constant_framerate_unsupported") {
    std::istringstream(value) >> std::boolalpha >>
        info->constant_framerate_unsupported;
  } else if (key == "quirks") {
    info->quirks = ParseQuirks(value);
  } else if (key == "lens_facing") {
    info->lens_facing = stoi(value);
  } else if (key == "sensor_orientation") {
    info->sensor_orientation = stoi(value);
  } else if (key == "lens_info_available_apertures") {
    info->lens_info_available_apertures = ParseCommaSeparated<float>(value);
  } else if (key == "lens_info_available_focal_lengths") {
    info->lens_info_available_focal_lengths = ParseCommaSeparated<float>(value);
  } else if (key == "lens_info_minimum_focus_distance") {
    info->lens_info_minimum_focus_distance = stof(value);
  } else if (key == "lens_info_optimal_focus_distance") {
    info->lens_info_optimal_focus_distance = stof(value);
  } else if (key == "sensor_info_physical_size") {
    ParseSize(value, &info->sensor_info_physical_size_width,
              &info->sensor_info_physical_size_height);
  } else if (key == "sensor_info_pixel_array_size") {
    ParseSize(value, &info->sensor_info_pixel_array_size_width,
              &info->sensor_info_pixel_array_size_height);
  } else if (IsUsbV1Key(key)) {
    VLOGF(1) << "Ignored v1 key: " << key << " value: " << value;
  } else {
    LOGF(ERROR) << "Unknown key: " << key << " value: " << value;
  }
}

}  // namespace

// static
bool CameraCharacteristics::ConfigFileExists() {
  return base::PathExists(kCameraCharacteristicsConfigFile);
}

CameraCharacteristics::CameraCharacteristics() {
  if (ConfigFileExists()) {
    InitFrom(kCameraCharacteristicsConfigFile);
  }
}

CameraCharacteristics::CameraCharacteristics(
    const base::FilePath& config_file) {
  InitFrom(config_file);
}

void CameraCharacteristics::InitFrom(const base::FilePath& config_file) {
  CHECK(base::PathExists(config_file))
      << config_file.value() << " does not exist";
  std::ifstream ifs(config_file.value());
  CHECK(ifs.good()) << "Can't open file " << config_file.value();

  // Used as per_camera_infos[camera_id].
  DeviceInfos per_camera_infos;

  // Used as per_module_infos[camera_id][module_id].
  std::vector<DeviceInfos> per_module_infos;

  for (std::string line; std::getline(ifs, line);) {
    line = base::ToLowerASCII(base::TrimWhitespaceASCII(line, base::TRIM_ALL));

    // Skip empty lines and comments.
    if (line.empty() || line[0] == '#') {
      continue;
    }

    size_t camera_id, module_id;
    std::string key, value;

    if (RE2::FullMatch(line, R"(camera(\d+)\.([^.=]+)=(.+))", &camera_id, &key,
                       &value)) {
      // camera{x}.{key}={value}
      if (camera_id == per_camera_infos.size()) {
        per_camera_infos.push_back({.camera_id = static_cast<int>(camera_id)});
        per_module_infos.push_back({});
      }
      CHECK(camera_id + 1 == per_camera_infos.size())
          << "Invalid camera id " << camera_id;
      CHECK(per_module_infos.back().empty())
          << "Module specific characteristics should come after camera "
             "specific ones";

      SetEntry(key, value, &per_camera_infos[camera_id]);
    } else if (RE2::FullMatch(line, R"(camera(\d+)\.module(\d+).([^.=]+)=(.+))",
                              &camera_id, &module_id, &key, &value)) {
      // camera{x}.module{y}.{key}={value}
      DeviceInfos& module_infos = per_module_infos[camera_id];
      if (module_id == module_infos.size()) {
        module_infos.push_back(per_camera_infos[camera_id]);
      }
      CHECK(module_id + 1 == module_infos.size())
          << "Invalid module id " << module_id;

      SetEntry(key, value, &module_infos[module_id]);
    } else {
      LOGF(FATAL) << "Failed to parse: " << line;
    }
  }

  for (const auto& camera_infos : per_module_infos) {
    for (const auto& module_info : camera_infos) {
      auto ret = camera_module_infos_.insert(
          {{module_info.usb_vid, module_info.usb_pid}, module_info});
      CHECK(ret.second) << "Duplicate vid:pid in config";
    }
  }
}

const DeviceInfo* CameraCharacteristics::Find(const std::string& vid,
                                              const std::string& pid) const {
  auto it = camera_module_infos_.find({vid, pid});
  if (it != camera_module_infos_.end()) {
    const DeviceInfo& info = it->second;
    VLOGF(1) << "Found camera" << info.camera_id << " in characteristics"
             << " with vid:pid = " << vid << ":" << pid;
    return &it->second;
  } else {
    VLOGF(1) << "No camera with vid:pid = " << vid << ":" << pid
             << " found in characteristics";
    return nullptr;
  }
}

}  // namespace cros
