// Copyright 2015 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/webdriver/web_driver_module.h"

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/base64.h"
#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/memory/ptr_util.h"
#include "base/trace_event/trace_event.h"
#include "base/values.h"
#include "cobalt/webdriver/dispatcher.h"
#include "cobalt/webdriver/protocol/capabilities.h"
#include "cobalt/webdriver/protocol/window_id.h"
#include "cobalt/webdriver/screencast/screencast_module.h"
#include "cobalt/webdriver/screenshot.h"
#include "cobalt/webdriver/server.h"
#include "cobalt/webdriver/session_driver.h"
#include "cobalt/webdriver/util/command_result.h"
#include "cobalt/webdriver/util/dispatch_command_factory.h"
#include "cobalt/webdriver/window_driver.h"

namespace cobalt {
namespace webdriver {
namespace {

// Only one session is supported. This is the session ID for that session.
const char kWebDriverSessionId[] = "session-0";

// Variable names for variable path components.
const char kSessionIdVariable[] = ":sessionId";
const char kWindowHandleVariable[] = ":windowHandle";
const char kElementId[] = ":id";
const char kOtherElementId[] = ":other";
const char kAttributeName[] = ":name";
const char kCssPropertyName[] = ":propertyName";
const char kCookieName[] = ":name";

// Error messages related to session creation.
const char kMaxSessionsCreatedMessage[] =
    "Maximum number of sessions have been created.";
const char kUnsupportedCapabilities[] =
    "An unsupported capability was requested.";
const char kUnknownSessionCreationError[] =
    "An unknown error occurred trying to create a new session.";

// Looks up the SessionDriver instance that is mapped to the
// the sessionId variable in the path.
SessionDriver* LookUpSessionDriverOrReturnInvalidResponse(
    const base::Callback<SessionDriver*(const protocol::SessionId&)>&
        get_session_cb,
    const WebDriverDispatcher::PathVariableMap* path_variables,
    WebDriverDispatcher::CommandResultHandler* result_handler) {
  DCHECK(path_variables);
  protocol::SessionId session_id(
      path_variables->GetVariable(kSessionIdVariable));

  SessionDriver* session_driver = get_session_cb.Run(session_id);
  // If there is no session with this ID, then return an error.
  if (!session_driver) {
    result_handler->SendInvalidRequestResponse(
        WebDriverDispatcher::CommandResultHandler::kInvalidPathVariable,
        session_id.id());
  }
  return session_driver;
}

// There are no path variables to look up in this case. Ignore the path
// variables and return the session's current window.
WindowDriver* LookUpCurrentWindowDriver(
    SessionDriver* session_driver,
    const WebDriverDispatcher::PathVariableMap* path_variables,
    WebDriverDispatcher::CommandResultHandler* result_handler) {
  DCHECK(session_driver);
  // If the current window has been closed, an error should be returned, but
  // we don't support closing windows on Cobalt.
  return session_driver->GetCurrentWindow();
}

// There are no path variables to look up in this case. This function simply
// returns the same SessionDriver that was passed in.
SessionDriver* LookUpSessionDriver(
    SessionDriver* session_driver,
    const WebDriverDispatcher::PathVariableMap* path_variables,
    WebDriverDispatcher::CommandResultHandler* result_handler) {
  DCHECK(session_driver);
  return session_driver;
}

// Looks up the WindowDriver instance that is mapped to the
// the sessionId variable in the path.
WindowDriver* LookUpWindowDriverOrReturnInvalidResponse(
    SessionDriver* session_driver,
    const WebDriverDispatcher::PathVariableMap* path_variables,
    WebDriverDispatcher::CommandResultHandler* result_handler) {
  DCHECK(path_variables);
  DCHECK(session_driver);
  protocol::WindowId window_id(
      path_variables->GetVariable(kWindowHandleVariable));
  WindowDriver* window_driver =
      session_driver->GetWindow(protocol::WindowId(window_id));
  if (!window_driver) {
    result_handler->SendInvalidRequestResponse(
        WebDriverDispatcher::CommandResultHandler::kInvalidPathVariable,
        window_id.id());
  }
  return window_driver;
}

// Looks up the ElementDriver instance that is mapped to the
// the sessionId variable in the path.
ElementDriver* LookUpElementDriverOrReturnInvalidResponse(
    const char* path_variable, SessionDriver* session_driver,
    const WebDriverDispatcher::PathVariableMap* path_variables,
    WebDriverDispatcher::CommandResultHandler* result_handler) {
  DCHECK(path_variables);
  DCHECK(session_driver);
  ElementDriver* element_driver = NULL;
  WindowDriver* window_driver =
      LookUpCurrentWindowDriver(session_driver, path_variables, result_handler);
  if (window_driver) {
    protocol::ElementId element_id(path_variables->GetVariable(path_variable));
    element_driver =
        window_driver->GetElementDriver(protocol::ElementId(element_id));
    if (!element_driver) {
      result_handler->SendInvalidRequestResponse(
          WebDriverDispatcher::CommandResultHandler::kInvalidPathVariable,
          element_id.id());
    }
  }
  return element_driver;
}

}  // namespace

WebDriverModule::WebDriverModule(
    int server_port, const std::string& listen_ip,
    const CreateSessionDriverCB& create_session_driver_cb,
    const GetScreenshotFunction& get_screenshot_function,
    const SetProxyFunction& set_proxy_function,
    const base::Closure& shutdown_cb)
    : listen_ip_(listen_ip),
      webdriver_thread_("WebDriverThread"),
      create_session_driver_cb_(create_session_driver_cb),
      get_screenshot_function_(get_screenshot_function),
      set_proxy_function_(set_proxy_function),
      shutdown_cb_(shutdown_cb),
      webdriver_dispatcher_(new WebDriverDispatcher()) {
  get_session_driver_ =
      base::Bind(&WebDriverModule::GetSessionDriver, base::Unretained(this));

  typedef util::DispatchCommandFactory<SessionDriver> SessionCommandFactory;
  typedef util::DispatchCommandFactory<WindowDriver> WindowCommandFactory;
  typedef util::DispatchCommandFactory<ElementDriver> ElementCommandFactory;

  scoped_refptr<SessionCommandFactory> session_command_factory(
      new SessionCommandFactory(
          base::Bind(&LookUpSessionDriverOrReturnInvalidResponse,
                     get_session_driver_),
          base::Bind(&LookUpSessionDriver)));

  scoped_refptr<WindowCommandFactory> current_window_command_factory(
      new WindowCommandFactory(
          base::Bind(&LookUpSessionDriverOrReturnInvalidResponse,
                     get_session_driver_),
          base::Bind(&LookUpCurrentWindowDriver)));

  scoped_refptr<WindowCommandFactory> window_command_factory(
      new WindowCommandFactory(
          base::Bind(&LookUpSessionDriverOrReturnInvalidResponse,
                     get_session_driver_),
          base::Bind(&LookUpWindowDriverOrReturnInvalidResponse)));

  scoped_refptr<ElementCommandFactory> element_command_factory(
      new ElementCommandFactory(
          base::Bind(&LookUpSessionDriverOrReturnInvalidResponse,
                     get_session_driver_),
          base::Bind(&LookUpElementDriverOrReturnInvalidResponse, kElementId)));

  // Server commands.
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kGet, "/status",
      base::Bind(&WebDriverModule::GetServerStatus, base::Unretained(this)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kPost, "/session",
      base::Bind(&WebDriverModule::CreateSession, base::Unretained(this)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kGet, "/sessions",
      base::Bind(&WebDriverModule::GetActiveSessions, base::Unretained(this)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kGet, "/shutdown",
      base::Bind(&WebDriverModule::Shutdown, base::Unretained(this)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kDelete,
      base::StringPrintf("/session/%s", kSessionIdVariable),
      base::Bind(&WebDriverModule::DeleteSession, base::Unretained(this)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kGet,
      base::StringPrintf("/session/%s/screenshot", kSessionIdVariable),
      base::Bind(&WebDriverModule::RequestScreenshot, base::Unretained(this)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kGet,
      base::StringPrintf("/session/%s/startscreencast", kSessionIdVariable),
      base::Bind(&WebDriverModule::StartScreencast, base::Unretained(this)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kGet,
      base::StringPrintf("/session/%s/stopscreencast", kSessionIdVariable),
      base::Bind(&WebDriverModule::StopScreencast, base::Unretained(this)));

  // Session commands.
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kGet,
      base::StringPrintf("/session/%s", kSessionIdVariable),
      session_command_factory->GetCommandHandler(
          base::Bind(&SessionDriver::GetCapabilities)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kGet,
      base::StringPrintf("/session/%s/window_handle", kSessionIdVariable),
      session_command_factory->GetCommandHandler(
          base::Bind(&SessionDriver::GetCurrentWindowHandle)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kGet,
      base::StringPrintf("/session/%s/window_handles", kSessionIdVariable),
      session_command_factory->GetCommandHandler(
          base::Bind(&SessionDriver::GetWindowHandles)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kGet,
      base::StringPrintf("/session/%s/alert_text", kSessionIdVariable),
      session_command_factory->GetCommandHandler(
          base::Bind(&SessionDriver::GetAlertText)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kPost,
      base::StringPrintf("/session/%s/window", kSessionIdVariable),
      session_command_factory->GetCommandHandler(
          base::Bind(&SessionDriver::SwitchToWindow)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kGet,
      base::StringPrintf("/session/%s/log/types", kSessionIdVariable),
      session_command_factory->GetCommandHandler(
          base::Bind(&SessionDriver::GetLogTypes)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kPost,
      base::StringPrintf("/session/%s/log", kSessionIdVariable),
      session_command_factory->GetCommandHandler(
          base::Bind(&SessionDriver::GetLog)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kPost,
      base::StringPrintf("/session/%s/url", kSessionIdVariable),
      session_command_factory->GetCommandHandler(
          base::Bind(&SessionDriver::Navigate)));

  // Specified window commands.
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kGet,
      base::StringPrintf("/session/%s/window/%s/size", kSessionIdVariable,
                         kWindowHandleVariable),
      window_command_factory->GetCommandHandler(
          base::Bind(&WindowDriver::GetWindowSize)));

  // Current window commands.
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kGet,
      base::StringPrintf("/session/%s/url", kSessionIdVariable),
      current_window_command_factory->GetCommandHandler(
          base::Bind(&WindowDriver::GetCurrentUrl)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kGet,
      base::StringPrintf("/session/%s/source", kSessionIdVariable),
      current_window_command_factory->GetCommandHandler(
          base::Bind(&WindowDriver::GetSource)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kGet,
      base::StringPrintf("/session/%s/title", kSessionIdVariable),
      current_window_command_factory->GetCommandHandler(
          base::Bind(&WindowDriver::GetTitle)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kPost,
      base::StringPrintf("/session/%s/execute", kSessionIdVariable),
      current_window_command_factory->GetCommandHandler(
          base::Bind(&WindowDriver::Execute)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kPost,
      base::StringPrintf("/session/%s/execute_async", kSessionIdVariable),
      current_window_command_factory->GetCommandHandler(
          base::Bind(&WindowDriver::ExecuteAsync)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kPost,
      base::StringPrintf("/session/%s/element", kSessionIdVariable),
      current_window_command_factory->GetCommandHandler(
          base::Bind(&WindowDriver::FindElement)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kPost,
      base::StringPrintf("/session/%s/elements", kSessionIdVariable),
      current_window_command_factory->GetCommandHandler(
          base::Bind(&WindowDriver::FindElements)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kPost,
      base::StringPrintf("/session/%s/keys", kSessionIdVariable),
      current_window_command_factory->GetCommandHandler(
          base::Bind(&WindowDriver::SendKeys)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kPost,
      base::StringPrintf("/session/%s/element/active", kSessionIdVariable),
      current_window_command_factory->GetCommandHandler(
          base::Bind(&WindowDriver::GetActiveElement)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kPost,
      base::StringPrintf("/session/%s/frame", kSessionIdVariable),
      current_window_command_factory->GetCommandHandler(
          base::Bind(&WindowDriver::SwitchFrame)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kGet,
      base::StringPrintf("/session/%s/cookie", kSessionIdVariable),
      current_window_command_factory->GetCommandHandler(
          base::Bind(&WindowDriver::GetAllCookies)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kGet,
      base::StringPrintf("/session/%s/cookie/%s", kSessionIdVariable,
                         kCookieName),
      base::Bind(&WebDriverModule::GetCookieByName, base::Unretained(this)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kPost,
      base::StringPrintf("/session/%s/cookie", kSessionIdVariable),
      current_window_command_factory->GetCommandHandler(
          base::Bind(&WindowDriver::AddCookie)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kPost,
      base::StringPrintf("/session/%s/moveto", kSessionIdVariable),
      current_window_command_factory->GetCommandHandler(
          base::Bind(&WindowDriver::MouseMoveTo)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kPost,
      base::StringPrintf("/session/%s/buttondown", kSessionIdVariable),
      current_window_command_factory->GetCommandHandler(
          base::Bind(&WindowDriver::MouseButtonDown)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kPost,
      base::StringPrintf("/session/%s/buttonup", kSessionIdVariable),
      current_window_command_factory->GetCommandHandler(
          base::Bind(&WindowDriver::MouseButtonUp)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kPost,
      base::StringPrintf("/session/%s/click", kSessionIdVariable),
      current_window_command_factory->GetCommandHandler(
          base::Bind(&WindowDriver::SendClick)));

  // Element commands.
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kGet,
      base::StringPrintf("/session/%s/element/%s/name", kSessionIdVariable,
                         kElementId),
      element_command_factory->GetCommandHandler(
          base::Bind(&ElementDriver::GetTagName)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kGet,
      base::StringPrintf("/session/%s/element/%s/text", kSessionIdVariable,
                         kElementId),
      element_command_factory->GetCommandHandler(
          base::Bind(&ElementDriver::GetText)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kGet,
      base::StringPrintf("/session/%s/element/%s/displayed", kSessionIdVariable,
                         kElementId),
      element_command_factory->GetCommandHandler(
          base::Bind(&ElementDriver::IsDisplayed)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kGet,
      base::StringPrintf("/session/%s/element/%s/rect", kSessionIdVariable,
                         kElementId),
      element_command_factory->GetCommandHandler(
          base::Bind(&ElementDriver::GetRect)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kGet,
      base::StringPrintf("/session/%s/element/%s/location", kSessionIdVariable,
                         kElementId),
      element_command_factory->GetCommandHandler(
          base::Bind(&ElementDriver::GetLocation)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kGet,
      base::StringPrintf("/session/%s/element/%s/size", kSessionIdVariable,
                         kElementId),
      element_command_factory->GetCommandHandler(
          base::Bind(&ElementDriver::GetSize)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kPost,
      base::StringPrintf("/session/%s/element/%s/value", kSessionIdVariable,
                         kElementId),
      element_command_factory->GetCommandHandler(
          base::Bind(&ElementDriver::SendKeys)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kPost,
      base::StringPrintf("/session/%s/element/%s/element", kSessionIdVariable,
                         kElementId),
      element_command_factory->GetCommandHandler(
          base::Bind(&ElementDriver::FindElement)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kPost,
      base::StringPrintf("/session/%s/element/%s/elements", kSessionIdVariable,
                         kElementId),
      element_command_factory->GetCommandHandler(
          base::Bind(&ElementDriver::FindElements)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kPost,
      base::StringPrintf("/session/%s/element/%s/click", kSessionIdVariable,
                         kElementId),
      element_command_factory->GetCommandHandler(
          base::Bind(&ElementDriver::SendClick)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kGet,
      base::StringPrintf("/session/%s/element/%s/equals/%s", kSessionIdVariable,
                         kElementId, kOtherElementId),
      base::Bind(&WebDriverModule::ElementEquals, base::Unretained(this)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kGet,
      base::StringPrintf("/session/%s/element/%s/attribute/%s",
                         kSessionIdVariable, kElementId, kAttributeName),
      base::Bind(&WebDriverModule::GetAttribute, base::Unretained(this)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kGet,
      base::StringPrintf("/session/%s/element/%s/css/%s", kSessionIdVariable,
                         kElementId, kCssPropertyName),
      base::Bind(&WebDriverModule::GetCssProperty, base::Unretained(this)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kGet,
      base::StringPrintf("/session/%s/element/%s/screenshot",
                         kSessionIdVariable, kElementId),
      base::Bind(&WebDriverModule::RequestElementScreenshot,
                 base::Unretained(this)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kPost,
      base::StringPrintf("/session/%s/timeouts", kSessionIdVariable),
      base::Bind(&WebDriverModule::IgnoreCommand, base::Unretained(this)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kPost,
      base::StringPrintf("/session/%s/timeouts/async_script",
                         kSessionIdVariable),
      base::Bind(&WebDriverModule::IgnoreCommand, base::Unretained(this)));
  webdriver_dispatcher_->RegisterCommand(
      WebDriverServer::kPost,
      base::StringPrintf("/session/%s/timeouts/implicit_wait",
                         kSessionIdVariable),
      base::Bind(&WebDriverModule::IgnoreCommand, base::Unretained(this)));

  // The WebDriver API implementation will be called on the HTTP server thread.
  DETACH_FROM_THREAD(thread_checker_);

  // Start the thread and create the HTTP server on that thread.
  webdriver_thread_.StartWithOptions(
      base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
  webdriver_thread_.message_loop()->task_runner()->PostTask(
      FROM_HERE, base::Bind(&WebDriverModule::StartServer,
                            base::Unretained(this), server_port, listen_ip));
}  // NOLINT(readability/fn_size)

WebDriverModule::~WebDriverModule() {
  webdriver_thread_.message_loop()->task_runner()->PostBlockingTask(
      FROM_HERE, base::Bind(&WebDriverModule::StopServerAndSession,
                            base::Unretained(this)));
  webdriver_thread_.Stop();
}  // NOLINT(readability/fn_size)

void WebDriverModule::OnWindowRecreated() {
  if (base::MessageLoop::current() != webdriver_thread_.message_loop()) {
    webdriver_thread_.message_loop()->task_runner()->PostTask(
        FROM_HERE, base::Bind(&WebDriverModule::OnWindowRecreated,
                              base::Unretained(this)));
    return;
  }
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  if (session_) {
    session_->RefreshWindowDriver();
  }
}

void WebDriverModule::StartServer(int server_port,
                                  const std::string& listen_ip) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  // Create a new WebDriverServer and pass in the Dispatcher.
  webdriver_server_.reset(new WebDriverServer(
      server_port, listen_ip,
      base::Bind(&WebDriverDispatcher::HandleWebDriverServerRequest,
                 base::Unretained(webdriver_dispatcher_.get())),
      "Cobalt.Server.WebDriver"));
}

void WebDriverModule::StopServerAndSession() {
  webdriver_server_.reset();
  session_.reset();
}

SessionDriver* WebDriverModule::GetSessionDriver(
    const protocol::SessionId& session_id) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  SessionDriver* session_driver = NULL;
  if (session_ && (session_->session_id() == session_id)) {
    return session_.get();
  }
  return NULL;
}

// https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#status
void WebDriverModule::GetServerStatus(
    const base::Value* parameters,
    const WebDriverDispatcher::PathVariableMap* path_variables,
    std::unique_ptr<WebDriverDispatcher::CommandResultHandler> result_handler) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  result_handler->SendResult(base::nullopt, protocol::Response::kSuccess,
                             protocol::ServerStatus::ToValue(status_));
}

// https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#sessions
void WebDriverModule::GetActiveSessions(
    const base::Value* parameters,
    const WebDriverDispatcher::PathVariableMap* path_variables,
    std::unique_ptr<WebDriverDispatcher::CommandResultHandler> result_handler) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  std::vector<protocol::SessionId> sessions;
  if (session_) {
    sessions.push_back(session_->session_id());
  }
  result_handler->SendResult(base::nullopt, protocol::Response::kSuccess,
                             util::internal::ToValue(sessions));
}

// https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#get-sessionsessionid
void WebDriverModule::CreateSession(
    const base::Value* parameters,
    const WebDriverDispatcher::PathVariableMap* path_variables,
    std::unique_ptr<WebDriverDispatcher::CommandResultHandler> result_handler) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  base::Optional<protocol::RequestedCapabilities> requested_capabilities =
      protocol::RequestedCapabilities::FromValue(parameters);
  if (!requested_capabilities) {
    result_handler->SendInvalidRequestResponse(
        WebDriverDispatcher::CommandResultHandler::kInvalidParameters, "");
    return;
  }

  util::CommandResult<protocol::Capabilities> command_result =
      CreateSessionInternal(requested_capabilities.value());

  base::Optional<protocol::SessionId> session_id;
  if (command_result.is_success()) {
    session_id = session_->session_id();
  }
  util::internal::ReturnResponse(session_id, command_result,
                                 result_handler.get());
}

// https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#delete-sessionsessionid
void WebDriverModule::DeleteSession(
    const base::Value* parameters,
    const WebDriverDispatcher::PathVariableMap* path_variables,
    std::unique_ptr<WebDriverDispatcher::CommandResultHandler> result_handler) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  if (session_) {
    // Extract the sessionId variable from the path
    std::string session_id_variable =
        path_variables->GetVariable(kSessionIdVariable);

    if (session_id_variable == session_->session_id().id()) {
      // If the sessionID matches, the delete the session.
      session_.reset();
    }
  }
  // If the session doesn't exist, then this is a no-op.
  result_handler->SendResult(base::nullopt, protocol::Response::kSuccess,
                             std::unique_ptr<base::Value>());
}

void WebDriverModule::StartScreencast(
    const base::Value* parameters,
    const WebDriverDispatcher::PathVariableMap* path_variables,
    std::unique_ptr<WebDriverDispatcher::CommandResultHandler> result_handler) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  SessionDriver* session_driver = LookUpSessionDriverOrReturnInvalidResponse(
      base::Bind(&WebDriverModule::GetSessionDriver, base::Unretained(this)),
      path_variables, result_handler.get());
  if (session_driver) {
    typedef util::CommandResult<std::string> CommandResult;

    int port = 3003;
    screencast_driver_module_.reset(new screencast::ScreencastModule(
        port, listen_ip_, get_screenshot_function_));

    CommandResult result =
        util::CommandResult<std::string>(std::to_string(port));
    util::internal::ReturnResponse(session_driver->session_id(), result,
                                   result_handler.get());
  }
}

void WebDriverModule::StopScreencast(
    const base::Value* parameters,
    const WebDriverDispatcher::PathVariableMap* path_variables,
    std::unique_ptr<WebDriverDispatcher::CommandResultHandler> result_handler) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  SessionDriver* session_driver = LookUpSessionDriverOrReturnInvalidResponse(
      base::Bind(&WebDriverModule::GetSessionDriver, base::Unretained(this)),
      path_variables, result_handler.get());
  if (session_driver) {
    typedef util::CommandResult<std::string> CommandResult;

    screencast_driver_module_.reset();

    CommandResult result = util::CommandResult<std::string>("Server stopped");
    util::internal::ReturnResponse(session_driver->session_id(), result,
                                   result_handler.get());
  }
}

// https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#sessionsessionidscreenshot
void WebDriverModule::RequestScreenshot(
    const base::Value* parameters,
    const WebDriverDispatcher::PathVariableMap* path_variables,
    std::unique_ptr<WebDriverDispatcher::CommandResultHandler> result_handler) {
  TRACE_EVENT0("cobalt::WebDriver", "WebDriverModule::RequestScreenshot()");
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  SessionDriver* session_driver = LookUpSessionDriverOrReturnInvalidResponse(
      base::Bind(&WebDriverModule::GetSessionDriver, base::Unretained(this)),
      path_variables, result_handler.get());
  if (session_driver) {
    typedef util::CommandResult<std::string> CommandResult;

    CommandResult result =
        Screenshot::RequestScreenshot(get_screenshot_function_,
                                      /*clip_rect=*/base::nullopt);
    util::internal::ReturnResponse(session_driver->session_id(), result,
                                   result_handler.get());
  }
}

void WebDriverModule::Shutdown(
    const base::Value* parameters,
    const WebDriverDispatcher::PathVariableMap* path_variables,
    std::unique_ptr<WebDriverDispatcher::CommandResultHandler> result_handler) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  // It's expected that the application will terminate, so it's okay to
  // leave the request hanging.
  shutdown_cb_.Run();
}

void WebDriverModule::ElementEquals(
    const base::Value* parameters,
    const WebDriverDispatcher::PathVariableMap* path_variables,
    std::unique_ptr<WebDriverDispatcher::CommandResultHandler> result_handler) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  SessionDriver* session_driver = LookUpSessionDriverOrReturnInvalidResponse(
      base::Bind(&WebDriverModule::GetSessionDriver, base::Unretained(this)),
      path_variables, result_handler.get());
  if (!session_driver) {
    return;
  }
  ElementDriver* element_driver = LookUpElementDriverOrReturnInvalidResponse(
      kElementId, session_driver, path_variables, result_handler.get());
  if (!element_driver) {
    return;
  }
  ElementDriver* other_element = LookUpElementDriverOrReturnInvalidResponse(
      kOtherElementId, session_driver, path_variables, result_handler.get());
  if (!other_element) {
    return;
  }

  typedef util::CommandResult<bool> CommandResult;

  CommandResult result = element_driver->Equals(other_element);
  util::internal::ReturnResponse(session_driver->session_id(), result,
                                 result_handler.get());
}

void WebDriverModule::GetAttribute(
    const base::Value* parameters,
    const WebDriverDispatcher::PathVariableMap* path_variables,
    std::unique_ptr<WebDriverDispatcher::CommandResultHandler> result_handler) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  SessionDriver* session_driver = LookUpSessionDriverOrReturnInvalidResponse(
      base::Bind(&WebDriverModule::GetSessionDriver, base::Unretained(this)),
      path_variables, result_handler.get());
  if (session_driver) {
    ElementDriver* element_driver = LookUpElementDriverOrReturnInvalidResponse(
        kElementId, session_driver, path_variables, result_handler.get());
    if (element_driver) {
      std::string attribute_name = path_variables->GetVariable(kAttributeName);

      typedef util::CommandResult<base::Optional<std::string> > CommandResult;
      CommandResult result =
          element_driver->GetAttribute(std::move(attribute_name));
      util::internal::ReturnResponse(session_driver->session_id(), result,
                                     result_handler.get());
    }
  }
}

void WebDriverModule::GetCssProperty(
    const base::Value* parameters,
    const WebDriverDispatcher::PathVariableMap* path_variables,
    std::unique_ptr<WebDriverDispatcher::CommandResultHandler> result_handler) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  SessionDriver* session_driver = LookUpSessionDriverOrReturnInvalidResponse(
      base::Bind(&WebDriverModule::GetSessionDriver, base::Unretained(this)),
      path_variables, result_handler.get());
  if (session_driver) {
    ElementDriver* element_driver = LookUpElementDriverOrReturnInvalidResponse(
        kElementId, session_driver, path_variables, result_handler.get());
    if (element_driver) {
      std::string property_name = path_variables->GetVariable(kCssPropertyName);

      typedef util::CommandResult<std::string> CommandResult;
      CommandResult result =
          element_driver->GetCssProperty(std::move(property_name));
      util::internal::ReturnResponse(session_driver->session_id(), result,
                                     result_handler.get());
    }
  }
}

void WebDriverModule::RequestElementScreenshot(
    const base::Value* parameters,
    const WebDriverDispatcher::PathVariableMap* path_variables,
    std::unique_ptr<WebDriverDispatcher::CommandResultHandler> result_handler) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  SessionDriver* session_driver = LookUpSessionDriverOrReturnInvalidResponse(
      base::Bind(&WebDriverModule::GetSessionDriver, base::Unretained(this)),
      path_variables, result_handler.get());
  if (session_driver) {
    ElementDriver* element_driver = LookUpElementDriverOrReturnInvalidResponse(
        kElementId, session_driver, path_variables, result_handler.get());
    if (element_driver) {
      typedef util::CommandResult<std::string> CommandResult;
      CommandResult result =
          element_driver->RequestScreenshot(get_screenshot_function_);
      util::internal::ReturnResponse(session_driver->session_id(), result,
                                     result_handler.get());
    }
  }
}

void WebDriverModule::GetCookieByName(
    const base::Value* parameters,
    const WebDriverDispatcher::PathVariableMap* path_variables,
    std::unique_ptr<WebDriverDispatcher::CommandResultHandler> result_handler) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  SessionDriver* session_driver = LookUpSessionDriverOrReturnInvalidResponse(
      base::Bind(&WebDriverModule::GetSessionDriver, base::Unretained(this)),
      path_variables, result_handler.get());
  if (session_driver) {
    WindowDriver* window_driver = session_driver->GetCurrentWindow();
    DCHECK(window_driver);
    if (window_driver) {
      std::string cookie_name = path_variables->GetVariable(kCookieName);

      typedef util::CommandResult<std::vector<protocol::Cookie> > CommandResult;
      CommandResult result = window_driver->GetCookie(std::string(cookie_name));
      util::internal::ReturnResponse(session_driver->session_id(), result,
                                     result_handler.get());
    }
  }
}

void WebDriverModule::IgnoreCommand(
    const base::Value* parameters,
    const WebDriverDispatcher::PathVariableMap* path_variables,
    std::unique_ptr<WebDriverDispatcher::CommandResultHandler> result_handler) {
  // TODO: Hook up and implement timeouts.
  return result_handler->SendResult(protocol::SessionId(kWebDriverSessionId),
                                    protocol::Response::kSuccess,
                                    std::make_unique<base::Value>());
}

util::CommandResult<protocol::Capabilities>
WebDriverModule::CreateSessionInternal(
    const protocol::RequestedCapabilities& requested_capabilities) {
  typedef util::CommandResult<protocol::Capabilities> CommandResult;

  if (session_) {
    // A session has already been created. We can only create one.
    return CommandResult(protocol::Response::kSessionNotCreatedException,
                         kMaxSessionsCreatedMessage);
  }

  // We will only ever create sessions with one set of capabilities. So ignore
  // the desired capabilities (for now).
  if (requested_capabilities.required() &&
      !requested_capabilities.required()->AreCapabilitiesSupported()) {
    return CommandResult(protocol::Response::kSessionNotCreatedException,
                         kUnsupportedCapabilities);
  }

  session_ =
      create_session_driver_cb_.Run(protocol::SessionId(kWebDriverSessionId));
  if (!session_) {
    // Some failure to create the new session.
    return CommandResult(protocol::Response::kUnknownError,
                         kUnknownSessionCreationError);
  }

  // If proxy settings were requested when the session was created, set them
  // now.
  base::Optional<protocol::Proxy> proxy_settings =
      requested_capabilities.desired().proxy();
  if (!proxy_settings && requested_capabilities.required()) {
    proxy_settings = requested_capabilities.required()->proxy();
  }
  if (proxy_settings) {
    set_proxy_function_.Run(proxy_settings->rules());
  }

  return session_->GetCapabilities();
}

}  // namespace webdriver
}  // namespace cobalt
