// Copyright (c) 2012 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 "cros-disks/usb_device_info.h"

#include <vector>

#include <base/logging.h>
#include <base/strings/string_split.h>
#include <base/strings/string_util.h>

#include "cros-disks/file_reader.h"

using base::FilePath;
using std::map;
using std::string;
using std::vector;

namespace cros_disks {

// A data structure for holding information of a USB device.
struct USBDeviceEntry {
  DeviceMediaType media_type;
};

USBDeviceInfo::USBDeviceInfo() {
}

USBDeviceInfo::~USBDeviceInfo() {
}

DeviceMediaType USBDeviceInfo::GetDeviceMediaType(
    const string& vendor_id, const string& product_id) const {
  CHECK(!vendor_id.empty()) << "Invalid vendor ID";
  CHECK(!product_id.empty()) << "Invalid product ID";

  string id = vendor_id + ":" + product_id;
  map<string, USBDeviceEntry>::const_iterator map_iterator = entries_.find(id);
  if (map_iterator != entries_.end())
    return map_iterator->second.media_type;
  return DEVICE_MEDIA_USB;
}

bool USBDeviceInfo::RetrieveFromFile(const string& path) {
  entries_.clear();

  FileReader reader;
  if (!reader.Open(FilePath(path))) {
    LOG(ERROR) << "Failed to retrieve USB device info from '" << path << "'";
    return false;
  }

  string line;
  while (reader.ReadLine(&line)) {
    if (IsLineSkippable(line))
      continue;

    vector<string> tokens = base::SplitString(line, " ", base::KEEP_WHITESPACE,
                                              base::SPLIT_WANT_ALL);
    if (tokens.size() >= 2) {
      USBDeviceEntry& entry = entries_[tokens[0]];
      entry.media_type = ConvertToDeviceMediaType(tokens[1]);
    }
  }
  return true;
}

bool USBDeviceInfo::GetVendorAndProductName(
    const string& ids_file, const string& vendor_id, const string& product_id,
    string* vendor_name, string* product_name) {
  vendor_name->clear();
  product_name->clear();

  FileReader reader;
  if (!reader.Open(FilePath(ids_file))) {
    LOG(ERROR) << "Failed to retrieve USB identifier database at '"
               << ids_file << "'";
    return false;
  }

  bool found_vendor = false;
  string line;
  while (reader.ReadLine(&line)) {
    if (IsLineSkippable(line))
      continue;

    string id, name;
    // If the target vendor ID is found, search for a matching product ID.
    if (found_vendor) {
      if (line[0] == '\t' &&
          ExtractIdAndName(line.substr(1), &id, &name)) {
        if (id == product_id) {
          *product_name = name;
          break;
        }
        continue;
      }

      // If the line does not contain any product info, assume a new
      // section has started and no product info will be found for the
      // target ID. Return immediately.
      break;
    }

    // Skip forward until the target vendor ID is found.
    if (ExtractIdAndName(line, &id, &name)) {
      if (id == vendor_id) {
        *vendor_name = name;
        found_vendor = true;
      }
    }
  }

  return found_vendor;
}

DeviceMediaType USBDeviceInfo::ConvertToDeviceMediaType(
    const string& str) const {
  if (str == "sd") {
    return DEVICE_MEDIA_SD;
  } else if (str == "mobile") {
    return DEVICE_MEDIA_MOBILE;
  } else {
    return DEVICE_MEDIA_USB;
  }
}

bool USBDeviceInfo::IsLineSkippable(const string& line) const {
  string trimmed_line;
  // Trim only ASCII whitespace for now.
  base::TrimWhitespaceASCII(line, base::TRIM_ALL, &trimmed_line);
  return trimmed_line.empty() ||
         base::StartsWith(trimmed_line, "#", base::CompareCase::SENSITIVE);
}

bool USBDeviceInfo::ExtractIdAndName(
    const string& line, string* id, string* name) const {
  if ((line.length() > 6) &&
      base::IsHexDigit(line[0]) && base::IsHexDigit(line[1]) &&
      base::IsHexDigit(line[2]) && base::IsHexDigit(line[3]) &&
      (line[4] == ' ') && (line[5] == ' ')) {
    *id = base::ToLowerASCII(line.substr(0, 4));
    *name = line.substr(6);
    return true;
  }
  return false;
}

}  // namespace cros_disks
