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

#include <utility>

#include "base/memory/ptr_util.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "chrome/browser/devtools/device/android_device_manager.h"
#include "chrome/browser/devtools/device/tcp_device_provider.h"
#include "chrome/browser/devtools/devtools_network_protocol_handler.h"
#include "chrome/browser/devtools/devtools_protocol_constants.h"
#include "chrome/browser/devtools/devtools_window.h"
#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/browser_navigator.h"
#include "chrome/browser/ui/browser_navigator_params.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/exclusive_access/exclusive_access_context.h"
#include "chrome/browser/ui/tab_contents/tab_contents_iterator.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/grit/browser_resources.h"
#include "components/guest_view/browser/guest_view_base.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "extensions/browser/extension_host.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/process_manager.h"
#include "ui/base/resource/resource_bundle.h"

using content::DevToolsAgentHost;

char ChromeDevToolsManagerDelegate::kTypeApp[] = "app";
char ChromeDevToolsManagerDelegate::kTypeBackgroundPage[] = "background_page";
char ChromeDevToolsManagerDelegate::kTypeWebView[] = "webview";

namespace {

char kLocationsParam[] = "locations";
char kHostParam[] = "host";
char kPortParam[] = "port";

BrowserWindow* GetBrowserWindow(int window_id) {
  for (auto* b : *BrowserList::GetInstance()) {
    if (b->session_id().id() == window_id)
      return b->window();
  }
  return nullptr;
}

// Get the bounds and state of the browser window. The bounds is for the
// restored window when the window is minimized. Otherwise, it is for the actual
// window.
std::unique_ptr<base::DictionaryValue> GetBounds(BrowserWindow* window) {
  gfx::Rect bounds;
  if (window->IsMinimized())
    bounds = window->GetRestoredBounds();
  else
    bounds = window->GetBounds();

  auto bounds_object = base::MakeUnique<base::DictionaryValue>();

  bounds_object->SetInteger("left", bounds.x());
  bounds_object->SetInteger("top", bounds.y());
  bounds_object->SetInteger("width", bounds.width());
  bounds_object->SetInteger("height", bounds.height());

  std::string window_state = "normal";
  if (window->IsMinimized())
    window_state = "minimized";
  if (window->IsMaximized())
    window_state = "maximized";
  if (window->IsFullscreen())
    window_state = "fullscreen";
  bounds_object->SetString("windowState", window_state);

  return bounds_object;
}

bool GetExtensionInfo(content::RenderFrameHost* host,
                      std::string* name,
                      std::string* type) {
  content::WebContents* wc = content::WebContents::FromRenderFrameHost(host);
  if (!wc)
    return false;
  Profile* profile = Profile::FromBrowserContext(wc->GetBrowserContext());
  if (!profile)
    return false;
  const extensions::Extension* extension =
      extensions::ProcessManager::Get(profile)->GetExtensionForRenderFrameHost(
          host);
  if (!extension)
    return false;
  extensions::ExtensionHost* extension_host =
      extensions::ProcessManager::Get(profile)->GetBackgroundHostForExtension(
          extension->id());
  if (extension_host && extension_host->host_contents() == wc) {
    *name = extension->name();
    *type = ChromeDevToolsManagerDelegate::kTypeBackgroundPage;
    return true;
  } else if (extension->is_hosted_app() ||
             extension->is_legacy_packaged_app() ||
             extension->is_platform_app()) {
    *name = extension->name();
    *type = ChromeDevToolsManagerDelegate::kTypeApp;
    return true;
  }
  return false;
}

}  // namespace

// static
std::unique_ptr<base::DictionaryValue>
ChromeDevToolsManagerDelegate::GetWindowForTarget(
    int id,
    base::DictionaryValue* params) {
  std::string target_id;
  if (!params->GetString("targetId", &target_id))
    return DevToolsProtocol::CreateInvalidParamsResponse(id, "targetId");

  Browser* browser = nullptr;
  scoped_refptr<DevToolsAgentHost> host =
      DevToolsAgentHost::GetForId(target_id);
  if (!host)
    return DevToolsProtocol::CreateErrorResponse(id, "No target with given id");
  content::WebContents* web_contents = host->GetWebContents();
  if (!web_contents) {
    return DevToolsProtocol::CreateErrorResponse(
        id, "No web contents in the target");
  }
  for (auto* b : *BrowserList::GetInstance()) {
    int tab_index = b->tab_strip_model()->GetIndexOfWebContents(web_contents);
    if (tab_index != TabStripModel::kNoTab)
      browser = b;
  }
  if (!browser) {
    return DevToolsProtocol::CreateErrorResponse(id,
                                                 "Browser window not found");
  }

  auto result = base::MakeUnique<base::DictionaryValue>();
  result->SetInteger("windowId", browser->session_id().id());
  result->Set("bounds", GetBounds(browser->window()));
  return DevToolsProtocol::CreateSuccessResponse(id, std::move(result));
}

// static
std::unique_ptr<base::DictionaryValue>
ChromeDevToolsManagerDelegate::GetWindowBounds(int id,
                                               base::DictionaryValue* params) {
  int window_id;
  if (!params->GetInteger("windowId", &window_id))
    return DevToolsProtocol::CreateInvalidParamsResponse(id, "windowId");
  BrowserWindow* window = GetBrowserWindow(window_id);
  if (!window) {
    return DevToolsProtocol::CreateErrorResponse(id,
                                                 "Browser window not found");
  }

  auto result = base::MakeUnique<base::DictionaryValue>();
  result->Set("bounds", GetBounds(window));
  return DevToolsProtocol::CreateSuccessResponse(id, std::move(result));
}

// static
std::unique_ptr<base::DictionaryValue>
ChromeDevToolsManagerDelegate::SetWindowBounds(int id,
                                               base::DictionaryValue* params) {
  int window_id;
  if (!params->GetInteger("windowId", &window_id))
    return DevToolsProtocol::CreateInvalidParamsResponse(id, "windowId");
  BrowserWindow* window = GetBrowserWindow(window_id);
  if (!window) {
    return DevToolsProtocol::CreateErrorResponse(id,
                                                 "Browser window not found");
  }

  const base::Value* value = nullptr;
  const base::DictionaryValue* bounds_dict = nullptr;
  if (!params->Get("bounds", &value) || !value->GetAsDictionary(&bounds_dict))
    return DevToolsProtocol::CreateInvalidParamsResponse(id, "bounds");

  std::string window_state;
  if (!bounds_dict->GetString("windowState", &window_state))
    window_state = "normal";
  else if (window_state != "normal" && window_state != "minimized" &&
           window_state != "maximized" && window_state != "fullscreen")
    return DevToolsProtocol::CreateInvalidParamsResponse(id, "windowState");

  // Compute updated bounds when window state is normal.
  bool set_bounds = false;
  gfx::Rect bounds = window->GetBounds();
  int left, top, width, height;
  if (bounds_dict->GetInteger("left", &left)) {
    bounds.set_x(left);
    set_bounds = true;
  }
  if (bounds_dict->GetInteger("top", &top)) {
    bounds.set_y(top);
    set_bounds = true;
  }
  if (bounds_dict->GetInteger("width", &width)) {
    if (width < 0)
      return DevToolsProtocol::CreateInvalidParamsResponse(id, "width");
    bounds.set_width(width);
    set_bounds = true;
  }
  if (bounds_dict->GetInteger("height", &height)) {
    if (height < 0)
      return DevToolsProtocol::CreateInvalidParamsResponse(id, "height");
    bounds.set_height(height);
    set_bounds = true;
  }

  if (set_bounds && window_state != "normal") {
    return DevToolsProtocol::CreateErrorResponse(
        id,
        "The 'minimized', 'maximized' and 'fullscreen' states cannot be "
        "combined with 'left', 'top', 'width' or 'height'");
  }

  if (set_bounds && (window->IsMinimized() || window->IsMaximized() ||
                     window->IsFullscreen())) {
    return DevToolsProtocol::CreateErrorResponse(
        id,
        "To resize minimized/maximized/fullscreen window, restore it to normal "
        "state first.");
  }

  if (window_state == "fullscreen") {
    if (window->IsMinimized()) {
      return DevToolsProtocol::CreateErrorResponse(id,
                                                   "To make minimized window "
                                                   "fullscreen, restore it to "
                                                   "normal state first.");
    }
    window->GetExclusiveAccessContext()->EnterFullscreen(
        GURL(), EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE);
  }

  if (window_state == "maximized") {
    if (window->IsMinimized() || window->IsFullscreen()) {
      return DevToolsProtocol::CreateErrorResponse(
          id,
          "To maximize a minimized or fullscreen window, restore it to normal "
          "state first.");
    }
    window->Maximize();
  }

  if (window_state == "minimized") {
    if (window->IsFullscreen()) {
      return DevToolsProtocol::CreateErrorResponse(
          id,
          "To minimize a fullscreen window, restore it to normal "
          "state first.");
    }
    window->Minimize();
  }

  if (window_state == "normal") {
    if (window->IsFullscreen()) {
      window->GetExclusiveAccessContext()->ExitFullscreen();
    } else if (window->IsMinimized()) {
      window->Show();
    } else if (window->IsMaximized()) {
      window->Restore();
    } else if (set_bounds) {
      window->SetBounds(bounds);
    }
  }

  return DevToolsProtocol::CreateSuccessResponse(id, nullptr);
}

std::unique_ptr<base::DictionaryValue>
ChromeDevToolsManagerDelegate::HandleBrowserCommand(
    int id,
    std::string method,
    base::DictionaryValue* params) {
  if (method == chrome::devtools::Browser::getWindowForTarget::kName)
    return GetWindowForTarget(id, params);
  if (method == chrome::devtools::Browser::getWindowBounds::kName)
    return GetWindowBounds(id, params);
  if (method == chrome::devtools::Browser::setWindowBounds::kName)
    return SetWindowBounds(id, params);
  return nullptr;
}

class ChromeDevToolsManagerDelegate::HostData {
 public:
  HostData() {}
  ~HostData() {}

  RemoteLocations& remote_locations() { return remote_locations_; }

  void set_remote_locations(RemoteLocations& locations) {
    remote_locations_.swap(locations);
  }

 private:
  RemoteLocations remote_locations_;
};

ChromeDevToolsManagerDelegate::ChromeDevToolsManagerDelegate()
    : network_protocol_handler_(new DevToolsNetworkProtocolHandler()) {
  content::DevToolsAgentHost::AddObserver(this);
}

ChromeDevToolsManagerDelegate::~ChromeDevToolsManagerDelegate() {
  content::DevToolsAgentHost::RemoveObserver(this);
}

void ChromeDevToolsManagerDelegate::Inspect(
    content::DevToolsAgentHost* agent_host) {
  DevToolsWindow::OpenDevToolsWindow(agent_host, nullptr);
}

base::DictionaryValue* ChromeDevToolsManagerDelegate::HandleCommand(
    DevToolsAgentHost* agent_host,
    base::DictionaryValue* command_dict) {

  int id = 0;
  std::string method;
  base::DictionaryValue* params = nullptr;
  if (!DevToolsProtocol::ParseCommand(command_dict, &id, &method, &params))
    return nullptr;

  if (agent_host->GetType() == DevToolsAgentHost::kTypeBrowser &&
      method.find("Browser.") == 0)
    return HandleBrowserCommand(id, method, params).release();

  if (method == chrome::devtools::Target::setRemoteLocations::kName)
    return SetRemoteLocations(agent_host, id, params).release();

  return network_protocol_handler_->HandleCommand(agent_host, command_dict);
}

std::string ChromeDevToolsManagerDelegate::GetTargetType(
    content::RenderFrameHost* host) {
  content::WebContents* web_contents =
      content::WebContents::FromRenderFrameHost(host);

  guest_view::GuestViewBase* guest =
      guest_view::GuestViewBase::FromWebContents(web_contents);
  content::WebContents* guest_contents =
      guest ? guest->embedder_web_contents() : nullptr;
  if (guest_contents)
    return kTypeWebView;

  if (host->GetParent())
    return DevToolsAgentHost::kTypeFrame;

  for (TabContentsIterator it; !it.done(); it.Next()) {
    if (*it == web_contents)
      return DevToolsAgentHost::kTypePage;
  }

  std::string extension_name;
  std::string extension_type;
  if (!GetExtensionInfo(host, &extension_name, &extension_type))
    return DevToolsAgentHost::kTypeOther;
  return extension_type;
}

std::string ChromeDevToolsManagerDelegate::GetTargetTitle(
    content::RenderFrameHost* host) {
  std::string extension_name;
  std::string extension_type;
  if (!GetExtensionInfo(host, &extension_name, &extension_type))
    return std::string();
  return extension_name;
}

scoped_refptr<DevToolsAgentHost>
ChromeDevToolsManagerDelegate::CreateNewTarget(const GURL& url) {
  chrome::NavigateParams params(ProfileManager::GetLastUsedProfile(),
      url, ui::PAGE_TRANSITION_AUTO_TOPLEVEL);
  params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
  chrome::Navigate(&params);
  if (!params.target_contents)
    return nullptr;
  return DevToolsAgentHost::GetOrCreateFor(params.target_contents);
}

std::string ChromeDevToolsManagerDelegate::GetDiscoveryPageHTML() {
  return ResourceBundle::GetSharedInstance().GetRawDataResource(
      IDR_DEVTOOLS_DISCOVERY_PAGE_HTML).as_string();
}

std::string ChromeDevToolsManagerDelegate::GetFrontendResource(
    const std::string& path) {
  return content::DevToolsFrontendHost::GetFrontendResource(path).as_string();
}

void ChromeDevToolsManagerDelegate::DevToolsAgentHostAttached(
    content::DevToolsAgentHost* agent_host) {
  network_protocol_handler_->DevToolsAgentStateChanged(agent_host, true);

  DCHECK(host_data_.find(agent_host) == host_data_.end());
  host_data_[agent_host].reset(new ChromeDevToolsManagerDelegate::HostData());
}

void ChromeDevToolsManagerDelegate::DevToolsAgentHostDetached(
    content::DevToolsAgentHost* agent_host) {
  network_protocol_handler_->DevToolsAgentStateChanged(agent_host, false);
  // This class is created lazily, so it may not know about some attached hosts.
  if (host_data_.find(agent_host) != host_data_.end()) {
    host_data_.erase(agent_host);
    UpdateDeviceDiscovery();
  }
}

void ChromeDevToolsManagerDelegate::DevicesAvailable(
    const DevToolsDeviceDiscovery::CompleteDevices& devices) {
  DevToolsAgentHost::List remote_targets;
  for (const auto& complete : devices) {
    for (const auto& browser : complete.second->browsers()) {
      for (const auto& page : browser->pages())
        remote_targets.push_back(page->CreateTarget());
    }
  }
  remote_agent_hosts_.swap(remote_targets);
}

void ChromeDevToolsManagerDelegate::UpdateDeviceDiscovery() {
  RemoteLocations remote_locations;
  for (const auto& pair : host_data_) {
    RemoteLocations& locations = pair.second->remote_locations();
    remote_locations.insert(locations.begin(), locations.end());
  }

  bool equals = remote_locations.size() == remote_locations_.size();
  if (equals) {
    RemoteLocations::iterator it1 = remote_locations.begin();
    RemoteLocations::iterator it2 = remote_locations_.begin();
    while (it1 != remote_locations.end()) {
      DCHECK(it2 != remote_locations_.end());
      if (!(*it1).Equals(*it2))
        equals = false;
      ++it1;
      ++it2;
    }
    DCHECK(it2 == remote_locations_.end());
  }

  if (equals)
    return;

  if (remote_locations.empty()) {
    device_discovery_.reset();
    remote_agent_hosts_.clear();
  } else {
    if (!device_manager_)
      device_manager_ = AndroidDeviceManager::Create();

    AndroidDeviceManager::DeviceProviders providers;
    providers.push_back(new TCPDeviceProvider(remote_locations));
    device_manager_->SetDeviceProviders(providers);

    device_discovery_.reset(new DevToolsDeviceDiscovery(device_manager_.get(),
        base::Bind(&ChromeDevToolsManagerDelegate::DevicesAvailable,
                   base::Unretained(this))));
  }
  remote_locations_.swap(remote_locations);
}

std::unique_ptr<base::DictionaryValue>
ChromeDevToolsManagerDelegate::SetRemoteLocations(
    content::DevToolsAgentHost* agent_host,
    int command_id,
    base::DictionaryValue* params) {
  // Could have been created late.
  if (host_data_.find(agent_host) == host_data_.end())
    DevToolsAgentHostAttached(agent_host);

  std::set<net::HostPortPair> tcp_locations;
  base::ListValue* locations;
  if (!params->GetList(kLocationsParam, &locations))
    return DevToolsProtocol::CreateInvalidParamsResponse(command_id,
                                                         kLocationsParam);
  for (const auto& item : *locations) {
    if (!item.IsType(base::Value::Type::DICTIONARY)) {
      return DevToolsProtocol::CreateInvalidParamsResponse(command_id,
                                                           kLocationsParam);
    }
    const base::DictionaryValue* dictionary =
        static_cast<const base::DictionaryValue*>(&item);
    std::string host;
    if (!dictionary->GetStringWithoutPathExpansion(kHostParam, &host)) {
      return DevToolsProtocol::CreateInvalidParamsResponse(command_id,
                                                           kLocationsParam);
    }
    int port = 0;
    if (!dictionary->GetIntegerWithoutPathExpansion(kPortParam, &port)) {
      return DevToolsProtocol::CreateInvalidParamsResponse(command_id,
                                                           kLocationsParam);
    }
    tcp_locations.insert(net::HostPortPair(host, port));
  }

  host_data_[agent_host]->set_remote_locations(tcp_locations);
  UpdateDeviceDiscovery();

  return DevToolsProtocol::CreateSuccessResponse(command_id, nullptr);
}
