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

#include "runtime_probe/functions/input_device.h"

#include <pcrecpp.h>

#include <map>
#include <string>
#include <utility>
#include <vector>

#include <base/check_op.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/strings/string_split.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>

#include "runtime_probe/utils/file_utils.h"
#include "runtime_probe/utils/input_device.h"

namespace runtime_probe {

namespace {
constexpr auto kInputDevicesPath = "/proc/bus/input/devices";

using FieldType = std::pair<std::string, std::string>;

const std::vector<FieldType> kTouchscreenI2cFields = {
    {"name", "name"}, {"product", "hw_version"}, {"fw_version", "fw_version"}};
const std::map<std::string, std::string> kTouchscreenI2cDriverToVid = {
    {"elants_i2c", "04f3"}, {"raydium_ts", "27a3"}, {"atmel_ext_ts", "03eb"}};

std::string GetDriverName(const base::FilePath& node_path) {
  const auto driver_path = node_path.Append("driver");
  const auto real_driver_path = base::MakeAbsoluteFilePath(driver_path);
  if (real_driver_path.value().length() == 0)
    return "";
  const auto driver_name = real_driver_path.BaseName().value();
  return driver_name;
}

void FixTouchscreenI2cDevice(base::Value* device) {
  const auto* path = device->FindStringKey("path");
  if (!path)
    return;

  const auto* vid_old = device->FindStringKey("vendor");
  if (vid_old && *vid_old != "0000")
    return;

  const auto node_path = base::FilePath{*path}.Append("device");
  const auto driver_name = GetDriverName(node_path);
  const auto entry = kTouchscreenI2cDriverToVid.find(driver_name);
  if (entry == kTouchscreenI2cDriverToVid.end())
    return;

  // Refer to http://crrev.com/c/1825942.
  auto dict_value = MapFilesToDict(node_path, kTouchscreenI2cFields, {});
  if (!dict_value) {
    DVLOG(1) << "touchscreen_i2c-specific fields do not exist on node \""
             << node_path << "\"";
    return;
  }

  device->SetStringKey("vendor", entry->second);
  device->MergeDictionary(&*dict_value);
  return;
}

void AppendInputDevice(InputDeviceFunction::DataType* list_value,
                       std::unique_ptr<InputDeviceImpl> input_device,
                       const std::string& device_type_filter) {
  std::string device_type = input_device->type();
  if (!device_type_filter.empty() && device_type_filter != device_type)
    return;
  base::Value value(base::Value::Type::DICTIONARY);
  value.SetStringKey("bus", input_device->bus);
  value.SetStringKey("event", input_device->event);
  value.SetStringKey("name", input_device->name);
  value.SetStringKey("product", input_device->product);
  value.SetStringKey("vendor", input_device->vendor);
  value.SetStringKey("version", input_device->version);
  value.SetStringKey("path",
                     base::StringPrintf("/sys%s", input_device->sysfs.c_str()));
  value.SetStringKey("device_type", device_type);
  FixTouchscreenI2cDevice(&value);
  list_value->push_back(std::move(value));
}

}  // namespace

InputDeviceFunction::DataType InputDeviceFunction::EvalImpl() const {
  InputDeviceFunction::DataType results{};
  std::string input_devices_str;
  if (!base::ReadFileToString(base::FilePath(kInputDevicesPath),
                              &input_devices_str)) {
    LOG(ERROR) << "Failed to read " << kInputDevicesPath << ".";
    return {};
  }

  auto lines = base::SplitString(input_devices_str, "\n", base::TRIM_WHITESPACE,
                                 base::SPLIT_WANT_ALL);
  auto begin_iter = lines.cbegin();
  while (true) {
    auto end_iter = begin_iter;
    while (end_iter != lines.cend() && !end_iter->empty())
      ++end_iter;
    if (begin_iter != end_iter) {
      AppendInputDevice(
          &results,
          InputDeviceImpl::From(std::vector<std::string>(begin_iter, end_iter)),
          device_type_);
    }
    if (end_iter == lines.cend())
      break;
    begin_iter = std::next(end_iter);
  }
  return results;
}

}  // namespace runtime_probe
