/*
 * 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 = {
      "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>
Rect<T> ParseRect(const std::string& value) {
  Rect<T> r;
  CHECK(RE2::FullMatch(value, "(.*),(.*),(.*),(.*)", &r.left, &r.top, &r.right,
                       &r.bottom));
  CHECK(r.is_valid());
  return r;
}

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},
      {"report_least_fps_ranges", kQuirkReportLeastFpsRanges},
      {"v1device", kQuirkV1Device},
  };
  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 = static_cast<LensFacing>(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 (key == "sensor_info_active_array_size") {
    info->sensor_info_active_array_size = ParseRect<int32_t>(value);
  } else if (key == "horizontal_view_angle_16_9") {
    info->horizontal_view_angle_16_9 = stof(value);
  } else if (key == "horizontal_view_angle_4_3") {
    info->horizontal_view_angle_4_3 = stof(value);
  } else if (key == "vertical_view_angle_16_9") {
    info->vertical_view_angle_16_9 = stof(value);
  } else if (key == "vertical_view_angle_4_3") {
    info->vertical_view_angle_4_3 = stof(value);
  } 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
