// Copyright 2018 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 "headless/lib/browser/protocol/browser_handler.h"

#include "base/bind.h"
#include "base/task/post_task.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "headless/lib/browser/headless_browser_impl.h"
#include "headless/lib/browser/headless_web_contents_impl.h"

namespace headless {
namespace protocol {

namespace {

std::unique_ptr<Browser::Bounds> CreateBrowserBounds(
    const HeadlessWebContentsImpl* web_contents) {
  gfx::Rect bounds = web_contents->web_contents()->GetContainerBounds();
  return Browser::Bounds::Create()
      .SetLeft(bounds.x())
      .SetTop(bounds.y())
      .SetWidth(bounds.width())
      .SetHeight(bounds.height())
      .SetWindowState(web_contents->window_state())
      .Build();
}

}  // namespace

BrowserHandler::BrowserHandler(base::WeakPtr<HeadlessBrowserImpl> browser,
                               const std::string& target_id)
    : DomainHandler(Browser::Metainfo::domainName, browser),
      target_id_(target_id) {}

BrowserHandler::~BrowserHandler() = default;

void BrowserHandler::Wire(UberDispatcher* dispatcher) {
  Browser::Dispatcher::wire(dispatcher, this);
}

Response BrowserHandler::GetWindowForTarget(
    Maybe<std::string> target_id,
    int* out_window_id,
    std::unique_ptr<Browser::Bounds>* out_bounds) {
  HeadlessWebContentsImpl* web_contents = HeadlessWebContentsImpl::From(
      browser()->GetWebContentsForDevToolsAgentHostId(
          target_id.fromMaybe(target_id_)));
  if (!web_contents)
    return Response::Error("No web contents for the given target id");

  auto result = std::make_unique<base::DictionaryValue>();
  *out_window_id = web_contents->window_id();
  *out_bounds = CreateBrowserBounds(web_contents);
  return Response::OK();
}

Response BrowserHandler::GetWindowBounds(
    int window_id,
    std::unique_ptr<Browser::Bounds>* out_bounds) {
  HeadlessWebContentsImpl* web_contents =
      browser()->GetWebContentsForWindowId(window_id);
  if (!web_contents)
    return Response::Error("Browser window not found");
  *out_bounds = CreateBrowserBounds(web_contents);
  return Response::OK();
}

Response BrowserHandler::Close() {
  base::PostTask(FROM_HERE, {content::BrowserThread::UI},
                 base::BindOnce(&HeadlessBrowserImpl::Shutdown, browser()));
  return Response::OK();
}

Response BrowserHandler::SetWindowBounds(
    int window_id,
    std::unique_ptr<Browser::Bounds> window_bounds) {
  HeadlessWebContentsImpl* web_contents =
      browser()->GetWebContentsForWindowId(window_id);
  if (!web_contents)
    return Response::Error("Browser window not found");

  gfx::Rect bounds = web_contents->web_contents()->GetContainerBounds();
  const bool set_bounds = window_bounds->HasLeft() || window_bounds->HasTop() ||
                          window_bounds->HasWidth() ||
                          window_bounds->HasHeight();
  if (set_bounds) {
    bounds.set_x(window_bounds->GetLeft(bounds.x()));
    bounds.set_y(window_bounds->GetTop(bounds.y()));
    bounds.set_width(window_bounds->GetWidth(bounds.width()));
    bounds.set_height(window_bounds->GetHeight(bounds.height()));
  }

  const std::string window_state = window_bounds->GetWindowState("normal");
  if (set_bounds && window_state != "normal") {
    return Response::Error(
        "The 'minimized', 'maximized' and 'fullscreen' states cannot be "
        "combined with 'left', 'top', 'width' or 'height'");
  }

  if (set_bounds && web_contents->window_state() != "normal") {
    return Response::Error(
        "To resize minimized/maximized/fullscreen window, restore it to normal "
        "state first.");
  }

  web_contents->set_window_state(window_state);
  web_contents->SetBounds(bounds);
  return Response::OK();
}

protocol::Response BrowserHandler::SetDockTile(Maybe<std::string> label,
                                               Maybe<protocol::Binary> image) {
  return Response::OK();
}

}  // namespace protocol
}  // namespace headless
