// 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/check.h>
#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 {

// Attribute file in sysfs for PCI devices that indicate whether the PCI device
// is internal or external (0=internal, 1=external). This works because the
// firmware tags the external facing PCI ports by a flag that the kernel looks
// at, to determine whether a device is internal or external. This sysfs
// is something we couldnt reach agreement upstream with yet, and are carrying
// ourselves currently. Ref:
// https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/2511510
constexpr char kExternalAttribute[] = "untrusted";

// 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") {
    auto dev = ReadDeviceId(DeviceId::BusType::kPci, syspath.Append("vendor"),
                            syspath.Append("product"));

    std::string is_external;
    if (base::ReadFileToString(syspath.Append(kExternalAttribute),
                               &is_external) &&
        !is_external.empty()) {
      if (is_external == "0") {
        dev->location_type_ = LocationType::kInternal;
      } else {
        dev->location_type_ = LocationType::kExternal;
      }
    }
    return dev;
  } 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;
  }

  const char* loc;
  if (location_type_ == LocationType::kExternal)
    loc = " (External)";
  else if (location_type_ == LocationType::kInternal)
    loc = " (Internal)";
  else
    loc = "";

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

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

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

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

  // Check if match is specifically desired based on location type.
  if (pattern.location_type_.has_value() &&
      location_type_ != pattern.location_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();
}
