// 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/devtools_android_bridge.h"

#include <stddef.h>
#include <algorithm>
#include <map>
#include <set>
#include <utility>
#include <vector>

#include "base/base64.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/json/json_reader.h"
#include "base/lazy_instance.h"
#include "base/macros.h"
#include "base/memory/singleton.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread.h"
#include "base/values.h"
#include "chrome/browser/devtools/device/adb/adb_device_provider.h"
#include "chrome/browser/devtools/device/port_forwarding_controller.h"
#include "chrome/browser/devtools/device/tcp_device_provider.h"
#include "chrome/browser/devtools/device/usb/usb_device_provider.h"
#include "chrome/browser/devtools/devtools_window.h"
#include "chrome/browser/devtools/remote_debugging_server.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/buildflags.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/devtools_external_agent_proxy.h"
#include "content/public/browser/devtools_external_agent_proxy_delegate.h"
#include "net/base/escape.h"
#include "net/base/host_port_pair.h"
#include "net/base/net_errors.h"

#if BUILDFLAG(ENABLE_SERVICE_DISCOVERY)
#include "chrome/browser/devtools/device/cast_device_provider.h"
#endif

using content::BrowserThread;
using content::DevToolsAgentHost;

namespace {

const char kNewPageRequestWithURL[] = "/json/new?%s";
const char kChromeDiscoveryURL[] = "localhost:9222";
const char kNodeDiscoveryURL[] = "localhost:9229";

bool BrowserIdFromString(const std::string& browser_id_str,
                         std::string* serial,
                         std::string* browser_id) {
  size_t colon_pos = browser_id_str.find(':');
  if (colon_pos == std::string::npos)
    return false;
  *serial = browser_id_str.substr(0, colon_pos);
  *browser_id = browser_id_str.substr(colon_pos + 1);
  return true;
}

}  // namespace

// static
DevToolsAndroidBridge::Factory* DevToolsAndroidBridge::Factory::GetInstance() {
  return base::Singleton<DevToolsAndroidBridge::Factory>::get();
}

// static
DevToolsAndroidBridge* DevToolsAndroidBridge::Factory::GetForProfile(
    Profile* profile) {
  return static_cast<DevToolsAndroidBridge*>(GetInstance()->
          GetServiceForBrowserContext(profile->GetOriginalProfile(), true));
}

DevToolsAndroidBridge::Factory::Factory()
    : BrowserContextKeyedServiceFactory(
          "DevToolsAndroidBridge",
          BrowserContextDependencyManager::GetInstance()) {
}

DevToolsAndroidBridge::Factory::~Factory() {}

KeyedService* DevToolsAndroidBridge::Factory::BuildServiceInstanceFor(
    content::BrowserContext* context) const {
  Profile* profile = Profile::FromBrowserContext(context);

  return new DevToolsAndroidBridge(profile);
}

void DevToolsAndroidBridge::Shutdown() {
  // Needed for Chrome_DevToolsADBThread to shut down gracefully in tests.
  device_manager_.reset();
}

scoped_refptr<content::DevToolsAgentHost>
DevToolsAndroidBridge::GetBrowserAgentHost(
    scoped_refptr<RemoteBrowser> browser) {
  auto it = device_map_.find(browser->serial());
  if (it == device_map_.end())
    return nullptr;

  return DevToolsDeviceDiscovery::CreateBrowserAgentHost(it->second, browser);
}

void DevToolsAndroidBridge::SendJsonRequest(
    const std::string& browser_id_str,
    const std::string& url,
    const JsonRequestCallback& callback) {
  std::string serial;
  std::string browser_id;
  if (!BrowserIdFromString(browser_id_str, &serial, &browser_id)) {
    callback.Run(net::ERR_FAILED, std::string());
    return;
  }
  auto it = device_map_.find(serial);
  if (it == device_map_.end()) {
    callback.Run(net::ERR_FAILED, std::string());
    return;
  }
  it->second->SendJsonRequest(browser_id, url, callback);
}

void DevToolsAndroidBridge::OpenRemotePage(scoped_refptr<RemoteBrowser> browser,
                                           const std::string& input_url) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  GURL gurl(input_url);
  if (!gurl.is_valid()) {
    gurl = GURL("http://" + input_url);
    if (!gurl.is_valid())
      return;
  }
  std::string url = gurl.spec();
  RemoteBrowser::ParsedVersion parsed_version = browser->GetParsedVersion();

  std::string query = net::EscapeQueryParamValue(url, false /* use_plus */);
  std::string request =
      base::StringPrintf(kNewPageRequestWithURL, query.c_str());
  SendJsonRequest(browser->GetId(), request, base::DoNothing());
}

DevToolsAndroidBridge::DevToolsAndroidBridge(
    Profile* profile)
    : profile_(profile),
      device_manager_(AndroidDeviceManager::Create()),
      port_forwarding_controller_(new PortForwardingController(profile)),
      weak_factory_(this) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  pref_change_registrar_.Init(profile_->GetPrefs());
  pref_change_registrar_.Add(prefs::kDevToolsDiscoverUsbDevicesEnabled,
      base::Bind(&DevToolsAndroidBridge::CreateDeviceProviders,
                 base::Unretained(this)));
  pref_change_registrar_.Add(prefs::kDevToolsTCPDiscoveryConfig,
      base::Bind(&DevToolsAndroidBridge::CreateDeviceProviders,
                 base::Unretained(this)));
  pref_change_registrar_.Add(prefs::kDevToolsDiscoverTCPTargetsEnabled,
      base::Bind(&DevToolsAndroidBridge::CreateDeviceProviders,
                 base::Unretained(this)));
  base::Value target_discovery(base::Value::Type::LIST);
  target_discovery.GetList().emplace_back(kChromeDiscoveryURL);
  target_discovery.GetList().emplace_back(kNodeDiscoveryURL);
  profile->GetPrefs()->SetDefaultPrefValue(prefs::kDevToolsTCPDiscoveryConfig,
                                           std::move(target_discovery));
  CreateDeviceProviders();
}

void DevToolsAndroidBridge::AddDeviceListListener(
    DeviceListListener* listener) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  bool polling_was_off = !NeedsDeviceListPolling();
  device_list_listeners_.push_back(listener);
  if (polling_was_off)
    StartDeviceListPolling();
}

void DevToolsAndroidBridge::RemoveDeviceListListener(
    DeviceListListener* listener) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  auto it = std::find(device_list_listeners_.begin(),
                      device_list_listeners_.end(), listener);
  DCHECK(it != device_list_listeners_.end());
  device_list_listeners_.erase(it);
  if (!NeedsDeviceListPolling())
    StopDeviceListPolling();
}

void DevToolsAndroidBridge::AddDeviceCountListener(
    DeviceCountListener* listener) {
  device_count_listeners_.push_back(listener);
  if (device_count_listeners_.size() == 1)
    StartDeviceCountPolling();
}

void DevToolsAndroidBridge::RemoveDeviceCountListener(
    DeviceCountListener* listener) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  auto it = std::find(device_count_listeners_.begin(),
                      device_count_listeners_.end(), listener);
  DCHECK(it != device_count_listeners_.end());
  device_count_listeners_.erase(it);
  if (device_count_listeners_.empty())
    StopDeviceCountPolling();
}

void DevToolsAndroidBridge::AddPortForwardingListener(
    PortForwardingListener* listener) {
  bool polling_was_off = !NeedsDeviceListPolling();
  port_forwarding_listeners_.push_back(listener);
  if (polling_was_off)
    StartDeviceListPolling();
}

void DevToolsAndroidBridge::RemovePortForwardingListener(
    PortForwardingListener* listener) {
  auto it = std::find(port_forwarding_listeners_.begin(),
                      port_forwarding_listeners_.end(), listener);
  DCHECK(it != port_forwarding_listeners_.end());
  port_forwarding_listeners_.erase(it);
  if (!NeedsDeviceListPolling())
    StopDeviceListPolling();
}

DevToolsAndroidBridge::~DevToolsAndroidBridge() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  DCHECK(device_list_listeners_.empty());
  DCHECK(device_count_listeners_.empty());
  DCHECK(port_forwarding_listeners_.empty());
}

void DevToolsAndroidBridge::StartDeviceListPolling() {
  device_discovery_.reset(new DevToolsDeviceDiscovery(device_manager_.get(),
      base::Bind(&DevToolsAndroidBridge::ReceivedDeviceList,
                 base::Unretained(this))));
  if (!task_scheduler_.is_null())
    device_discovery_->SetScheduler(task_scheduler_);
}

void DevToolsAndroidBridge::StopDeviceListPolling() {
  device_discovery_.reset();
  device_map_.clear();
  port_forwarding_controller_->CloseAllConnections();
}

bool DevToolsAndroidBridge::NeedsDeviceListPolling() {
  return !device_list_listeners_.empty() || !port_forwarding_listeners_.empty();
}

void DevToolsAndroidBridge::ReceivedDeviceList(
    const CompleteDevices& complete_devices) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  device_map_.clear();
  RemoteDevices remote_devices;
  for (const auto& pair : complete_devices) {
    device_map_[pair.first->serial()] = pair.first;
    remote_devices.push_back(pair.second);
  }

  DeviceListListeners copy(device_list_listeners_);
  for (auto it = copy.begin(); it != copy.end(); ++it)
    (*it)->DeviceListChanged(remote_devices);

  ForwardingStatus status =
      port_forwarding_controller_->DeviceListChanged(complete_devices);
  PortForwardingListeners forwarding_listeners(port_forwarding_listeners_);
  for (auto it = forwarding_listeners.begin(); it != forwarding_listeners.end();
       ++it) {
    (*it)->PortStatusChanged(status);
  }
}

void DevToolsAndroidBridge::StartDeviceCountPolling() {
  device_count_callback_.Reset(
      base::Bind(&DevToolsAndroidBridge::ReceivedDeviceCount, AsWeakPtr()));
  RequestDeviceCount(device_count_callback_.callback());
}

void DevToolsAndroidBridge::StopDeviceCountPolling() {
  device_count_callback_.Cancel();
}

void DevToolsAndroidBridge::RequestDeviceCount(
    const base::Callback<void(int)>& callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  if (device_count_listeners_.empty() || callback.IsCancelled())
    return;

  device_manager_->CountDevices(callback);
}

void DevToolsAndroidBridge::ReceivedDeviceCount(int count) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  DeviceCountListeners copy(device_count_listeners_);
  for (auto it = copy.begin(); it != copy.end(); ++it)
    (*it)->DeviceCountChanged(count);

  if (device_count_listeners_.empty())
     return;

  task_scheduler_.Run(
      base::Bind(&DevToolsAndroidBridge::RequestDeviceCount,
                 AsWeakPtr(), device_count_callback_.callback()));
}

static std::set<net::HostPortPair> ParseTargetDiscoveryPreferenceValue(
    const base::ListValue* preferenceValue) {
  std::set<net::HostPortPair> targets;
  if (!preferenceValue || preferenceValue->empty())
    return targets;
  std::string address;
  for (size_t i = 0; i < preferenceValue->GetSize(); i++) {
    if (!preferenceValue->GetString(i, &address))
      continue;
    net::HostPortPair target = net::HostPortPair::FromString(address);
    if (target.IsEmpty()) {
      LOG(WARNING) << "Invalid target: " << address;
      continue;
    }
    targets.insert(target);
  }
  return targets;
}

static scoped_refptr<TCPDeviceProvider> CreateTCPDeviceProvider(
    const base::ListValue* targetDiscoveryConfig) {
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  std::set<net::HostPortPair> targets =
      ParseTargetDiscoveryPreferenceValue(targetDiscoveryConfig);
  if (targets.empty() &&
      !command_line->HasSwitch(switches::kRemoteDebuggingTargets))
    return nullptr;
  std::string value =
      command_line->GetSwitchValueASCII(switches::kRemoteDebuggingTargets);
  std::vector<std::string> addresses = base::SplitString(
      value, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
  for (const std::string& address : addresses) {
    net::HostPortPair target = net::HostPortPair::FromString(address);
    if (target.IsEmpty()) {
      LOG(WARNING) << "Invalid target: " << address;
      continue;
    }
    targets.insert(target);
  }
  if (targets.empty())
    return nullptr;
  return new TCPDeviceProvider(targets);
}

void DevToolsAndroidBridge::CreateDeviceProviders() {
  AndroidDeviceManager::DeviceProviders device_providers;
  PrefService* service = profile_->GetPrefs();
  const base::ListValue* targets =
      service->GetBoolean(prefs::kDevToolsDiscoverTCPTargetsEnabled)
          ? service->GetList(prefs::kDevToolsTCPDiscoveryConfig)
          : nullptr;
  scoped_refptr<TCPDeviceProvider> provider = CreateTCPDeviceProvider(targets);
  if (tcp_provider_callback_)
    tcp_provider_callback_.Run(provider);

  if (provider)
    device_providers.push_back(provider);

#if BUILDFLAG(ENABLE_SERVICE_DISCOVERY)
  device_providers.push_back(new CastDeviceProvider());
#endif

  device_providers.push_back(new AdbDeviceProvider());

  const PrefService::Preference* pref =
      service->FindPreference(prefs::kDevToolsDiscoverUsbDevicesEnabled);
  const base::Value* pref_value = pref->GetValue();

  bool enabled;
  if (pref_value->GetAsBoolean(&enabled) && enabled) {
    device_providers.push_back(new UsbDeviceProvider(profile_));
  }

  device_manager_->SetDeviceProviders(device_providers);
  if (NeedsDeviceListPolling()) {
    StopDeviceListPolling();
    StartDeviceListPolling();
  }
}

void DevToolsAndroidBridge::set_tcp_provider_callback_for_test(
    TCPProviderCallback callback) {
  tcp_provider_callback_ = callback;
  CreateDeviceProviders();
}

void DevToolsAndroidBridge::set_usb_device_manager_for_test(
    device::mojom::UsbDeviceManagerPtrInfo fake_usb_manager) {
  device_manager_->set_usb_device_manager_for_test(std::move(fake_usb_manager));
}
