// Copyright 2014 The Chromium 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 "chrome/browser/devtools/device/usb/usb_device_provider.h"

#include "base/strings/stringprintf.h"
#include "chrome/browser/devtools/device/adb/adb_device_info_query.h"
#include "chrome/browser/devtools/device/usb/android_rsa.h"
#include "chrome/browser/devtools/device/usb/android_usb_device.h"
#include "crypto/rsa_private_key.h"
#include "net/base/net_errors.h"
#include "net/socket/stream_socket.h"

namespace {

const char kLocalAbstractCommand[] = "localabstract:%s";

const int kBufferSize = 16 * 1024;

void OnOpenSocket(const UsbDeviceProvider::SocketCallback& callback,
                  net::StreamSocket* socket,
                  int result) {
  callback.Run(result, result == net::OK ? socket : NULL);
}

void OnRead(net::StreamSocket* socket,
            scoped_refptr<net::IOBuffer> buffer,
            const std::string& data,
            const UsbDeviceProvider::CommandCallback& callback,
            int result) {
  if (result <= 0) {
    callback.Run(result, result == 0 ? data : std::string());
    delete socket;
    return;
  }

  std::string new_data = data + std::string(buffer->data(), result);
  result =
      socket->Read(buffer,
                   kBufferSize,
                   base::Bind(&OnRead, socket, buffer, new_data, callback));
  if (result != net::ERR_IO_PENDING)
    OnRead(socket, buffer, new_data, callback, result);
}

void OpenedForCommand(const UsbDeviceProvider::CommandCallback& callback,
                      net::StreamSocket* socket,
                      int result) {
  if (result != net::OK) {
    callback.Run(result, std::string());
    return;
  }
  scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kBufferSize);
  result = socket->Read(
      buffer,
      kBufferSize,
      base::Bind(&OnRead, socket, buffer, std::string(), callback));
  if (result != net::ERR_IO_PENDING)
    OnRead(socket, buffer, std::string(), callback, result);
}

void RunCommand(scoped_refptr<AndroidUsbDevice> device,
                const std::string& command,
                const UsbDeviceProvider::CommandCallback& callback) {
  net::StreamSocket* socket = device->CreateSocket(command);
  if (!socket) {
    callback.Run(net::ERR_CONNECTION_FAILED, std::string());
    return;
  }
  int result = socket->Connect(base::Bind(&OpenedForCommand, callback, socket));
  if (result != net::ERR_IO_PENDING)
    callback.Run(result, std::string());
}

} // namespace

// static
void UsbDeviceProvider::CountDevices(
    const base::Callback<void(int)>& callback) {
  AndroidUsbDevice::CountDevices(callback);
}

UsbDeviceProvider::UsbDeviceProvider(Profile* profile){
  rsa_key_.reset(AndroidRSAPrivateKey(profile));
}

void UsbDeviceProvider::QueryDevices(const SerialsCallback& callback) {
  AndroidUsbDevice::Enumerate(
      rsa_key_.get(),
      base::Bind(&UsbDeviceProvider::EnumeratedDevices, this, callback));
}

void UsbDeviceProvider::QueryDeviceInfo(const std::string& serial,
                                        const DeviceInfoCallback& callback) {
  UsbDeviceMap::iterator it = device_map_.find(serial);
  if (it == device_map_.end() || !it->second->is_connected()) {
    AndroidDeviceManager::DeviceInfo offline_info;
    callback.Run(offline_info);
    return;
  }
  AdbDeviceInfoQuery::Start(base::Bind(&RunCommand, it->second), callback);
}

void UsbDeviceProvider::OpenSocket(const std::string& serial,
                                   const std::string& name,
                                   const SocketCallback& callback) {
  UsbDeviceMap::iterator it = device_map_.find(serial);
  if (it == device_map_.end()) {
    callback.Run(net::ERR_CONNECTION_FAILED, NULL);
    return;
  }
  std::string socket_name =
      base::StringPrintf(kLocalAbstractCommand, name.c_str());
  net::StreamSocket* socket = it->second->CreateSocket(socket_name);
  if (!socket) {
    callback.Run(net::ERR_CONNECTION_FAILED, NULL);
    return;
  }
  int result = socket->Connect(base::Bind(&OnOpenSocket, callback, socket));
  if (result != net::ERR_IO_PENDING)
    callback.Run(result, NULL);
}

void UsbDeviceProvider::ReleaseDevice(const std::string& serial) {
  device_map_.erase(serial);
}

UsbDeviceProvider::~UsbDeviceProvider() {
}

void UsbDeviceProvider::EnumeratedDevices(const SerialsCallback& callback,
                                          const AndroidUsbDevices& devices) {
  std::vector<std::string> result;
  device_map_.clear();
  for (AndroidUsbDevices::const_iterator it = devices.begin();
       it != devices.end(); ++it) {
    result.push_back((*it)->serial());
    device_map_[(*it)->serial()] = *it;
    (*it)->InitOnCallerThread();
  }
  callback.Run(result);
}

