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

#include "shill/device_id.h"

#include <inttypes.h>

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

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>

namespace shill {

namespace {

// Reads a file containing a string device ID and normalizes it by trimming
// whitespace and converting to lowercase.
bool ReadDeviceIdFile(const base::FilePath& path, std::string* out_id) {
  DCHECK(out_id);
  std::string contents;
  if (!base::ReadFileToString(path, &contents))
    return false;

  *out_id = base::CollapseWhitespaceASCII(base::ToLowerASCII(contents), true);
  return true;
}

bool HextetToUInt16(const std::string& input, uint16_t* output) {
  DCHECK(output);
  std::vector<uint8_t> bytes;
  if (!base::HexStringToBytes(input, &bytes))
    return false;

  if (bytes.size() != 2)
    return false;

  *output = bytes[0] << 8 | bytes[1];
  return true;
}

bool HexToUInt16(const std::string& input, uint16_t* output) {
  DCHECK(output);
  if (base::StartsWith(input, "0x", base::CompareCase::INSENSITIVE_ASCII)) {
    return HextetToUInt16(input.substr(2), output);
  }
  return HextetToUInt16(input, output);
}

std::unique_ptr<DeviceId> ReadDeviceId(DeviceId::BusType bus_type,
                                       const base::FilePath& vendor_path,
                                       const base::FilePath& product_path) {
  std::string vendor_id, product_id;
  uint16_t parsed_vendor_id, parsed_product_id;

  if (!ReadDeviceIdFile(vendor_path, &vendor_id) ||
      !HexToUInt16(vendor_id, &parsed_vendor_id)) {
    return std::make_unique<DeviceId>(bus_type);
  }

  if (!ReadDeviceIdFile(product_path, &product_id) ||
      !HexToUInt16(product_id, &parsed_product_id)) {
    return std::make_unique<DeviceId>(bus_type, parsed_vendor_id);
  }

  return std::make_unique<DeviceId>(bus_type, parsed_vendor_id,
                                    parsed_product_id);
}

}  // namespace

// static
std::unique_ptr<DeviceId> DeviceId::CreateFromSysfs(
    const base::FilePath& syspath) {
  if (syspath.empty()) {
    return nullptr;
  }

  base::FilePath subsystem;
  if (!base::ReadSymbolicLink(syspath.Append("subsystem"), &subsystem)) {
    return nullptr;
  }

  std::string bus_type = subsystem.BaseName().value();
  if (bus_type == "pci") {
    return ReadDeviceId(DeviceId::BusType::kPci, syspath.Append("vendor"),
                        syspath.Append("product"));
  } else if (bus_type == "usb") {
    return ReadDeviceId(DeviceId::BusType::kUsb, syspath.Append("idVendor"),
                        syspath.Append("idProduct"));
  }
  return nullptr;
}

std::string DeviceId::AsString() const {
  const char* bus_name;
  switch (bus_type_) {
    case BusType::kUsb:
      bus_name = "usb";
      break;
    case BusType::kPci:
      bus_name = "pci";
      break;
  }

  if (!vendor_id_.has_value()) {
    return base::StringPrintf("%s:*:*", bus_name);
  }

  if (!product_id_.has_value()) {
    return base::StringPrintf("%s:%04" PRIx16 ":*", bus_name,
                              vendor_id_.value());
  }

  return base::StringPrintf("%s:%04" PRIx16 ":%04" PRIx16, bus_name,
                            vendor_id_.value(), product_id_.value());
}

bool DeviceId::Match(const DeviceId& pattern) const {
  if (bus_type_ != pattern.bus_type_) {
    return false;
  }

  // If |pattern| vendor id is *, then they don't have to match VID and PID
  // values.
  if (!pattern.vendor_id_.has_value()) {
    return true;
  }
  // If |this| vendor id is *, then it can not match to |pattern| with specific
  // vendor id.
  if (!vendor_id_.has_value() ||
      vendor_id_.value() != pattern.vendor_id_.value()) {
    return false;
  }

  // If |pattern| product id is *, then they don't have to match PID values.
  if (!pattern.product_id_.has_value()) {
    return true;
  }
  // If |this| product id is *, then it can not match to |pattern| with specific
  // product id.
  return product_id_.has_value() &&
         product_id_.value() == pattern.product_id_.value();
}

}  // namespace shill

std::ostream& operator<<(std::ostream& stream,
                         const shill::DeviceId& device_id) {
  return stream << device_id.AsString();
}
