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

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

#include "base/bind.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/strings/string_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "net/server/http_server_request_info.h"
#include "net/server/http_server_response_info.h"

namespace cobalt {
namespace webdriver {
namespace {

const char kJsonContentType[] = "application/json;charset=UTF-8";
const char kTextPlainContentType[] = "text/plain";
constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
    net::DefineNetworkTrafficAnnotation("webdriver_server", "WebDriver Server");

WebDriverServer::HttpMethod StringToHttpMethod(const std::string& method) {
  if (base::LowerCaseEqualsASCII(method, "get")) {
    return WebDriverServer::kGet;
  } else if (base::LowerCaseEqualsASCII(method, "post")) {
    return WebDriverServer::kPost;
  } else if (base::LowerCaseEqualsASCII(method, "delete")) {
    return WebDriverServer::kDelete;
  }
  return WebDriverServer::kUnknownMethod;
}

std::string HttpMethodToString(WebDriverServer::HttpMethod method) {
  switch (method) {
    case WebDriverServer::kGet:
      return "GET";
    case WebDriverServer::kPost:
      return "POST";
    case WebDriverServer::kDelete:
      return "DELETE";
    case WebDriverServer::kUnknownMethod:
      return "UNKNOWN";
  }
  NOTREACHED();
  return "";
}

// Implementation of the ResponseHandler interface.
// A Delegate implementation will call the methods on this interface for
// successful, failed, and invalid requests.
// For each of these cases, prepare an appropriate Http Response according to
// the spec, and send it to the specified connection through the net::HttpServer
// instance.
class ResponseHandlerImpl : public WebDriverServer::ResponseHandler {
 public:
  ResponseHandlerImpl(net::HttpServer* server, int connection_id)
      : task_runner_(base::ThreadTaskRunnerHandle::Get()),
        server_(server),
        connection_id_(connection_id) {}

  // https://www.selenium.dev/documentation/legacy/json_wire_protocol/#responses
  void Success(std::unique_ptr<base::Value> value) override {
    DCHECK(value);
    std::string data;
    base::JSONWriter::Write(*value, &data);
    SendInternal(net::HTTP_OK, data, kJsonContentType);
  }

  void SuccessData(const std::string& content_type, const char* data,
                   int len) override {
    std::string data_copied(data, len);
    server_->Send(connection_id_, net::HTTP_OK, data_copied, content_type,
                  kTrafficAnnotation);
  }

  // Failed commands map to a valid WebDriver command and contain the expected
  // parameters, but otherwise failed to execute for some reason. This should
  // send a 500 Internal Server Error.
  // https://www.selenium.dev/documentation/legacy/json_wire_protocol/#error-handling
  void FailedCommand(std::unique_ptr<base::Value> value) override {
    DCHECK(value);
    std::string data;
    base::JSONWriter::Write(*value, &data);
    SendInternal(net::HTTP_INTERNAL_SERVER_ERROR, data, kJsonContentType);
  }

  // A number of cases for invalid requests are explained here:
  // https://www.selenium.dev/documentation/legacy/json_wire_protocol/#invalid-requests
  // The response type should be text/plain and the message body is an error
  // message

  // The command request is not mapped to anything.
  void UnknownCommand(const std::string& path) override {
    LOG(INFO) << "Unknown command: " << path;
    SendInternal(net::HTTP_NOT_FOUND, "Unknown command", kTextPlainContentType);
  }

  // The command request is mapped to a valid command, but this WebDriver
  // implementation has not implemented it.
  void UnimplementedCommand(const std::string& path) override {
    LOG(INFO) << "Unimplemented command: " << path;
    SendInternal(net::HTTP_NOT_IMPLEMENTED, "Unimplemented command",
                 kTextPlainContentType);
  }

  // The request maps to a valid command, but the variable part of the path
  // does not map to a valid instance.
  void VariableResourceNotFound(const std::string& variable_name) override {
    SendInternal(net::HTTP_NOT_FOUND,
                 "Unknown variable resource: " + variable_name,
                 kTextPlainContentType);
  }

  // The request maps to a valid command, but with an unsupported Http method.
  void InvalidCommandMethod(WebDriverServer::HttpMethod requested_method,
                            const std::vector<WebDriverServer::HttpMethod>&
                                allowed_methods) override {
    DCHECK(!allowed_methods.empty());
    std::vector<std::string> allowed_method_strings;
    for (int i = 0; i < allowed_methods.size(); ++i) {
      allowed_method_strings.push_back(HttpMethodToString(allowed_methods[i]));
    }
    net::HttpServerResponseInfo response_info;
    response_info.AddHeader("Allow",
                            base::JoinString(allowed_method_strings, ", "));
    SendInternal(net::HTTP_METHOD_NOT_ALLOWED,
                 "Invalid method: " + HttpMethodToString(requested_method),
                 kTextPlainContentType, response_info);
  }

  // The POST command's JSON request body does not contain the required
  // parameters.
  void MissingCommandParameters(const std::string& message) override {
    SendInternal(net::HTTP_BAD_REQUEST, message, kTextPlainContentType);
  }

 private:
  static void SendToServer(
      net::HttpServer* server, int connection_id, net::HttpStatusCode status,
      const std::string& message, const std::string& content_type,
      const base::Optional<net::HttpServerResponseInfo>& response_info) {
    if (response_info) {
      server->SendResponse(connection_id, response_info.value(),
                           kTrafficAnnotation);
    }
    server->Send(connection_id, status, message, content_type,
                 kTrafficAnnotation);
  }

  // Send a response on the Http Server's thread.
  void SendInternal(net::HttpStatusCode status, const std::string& message,
                    const std::string& content_type,
                    base::Optional<net::HttpServerResponseInfo> response_info =
                        base::Optional<net::HttpServerResponseInfo>()) {
    if (base::ThreadTaskRunnerHandle::Get() == task_runner_) {
      SendToServer(server_, connection_id_, status, message, content_type,
                   response_info);
    } else {
      base::Closure closure =
          base::Bind(&SendToServer, server_, connection_id_, status, message,
                     content_type, response_info);
      task_runner_->PostTask(FROM_HERE, closure);
    }
  }

  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
  net::HttpServer* server_;
  int connection_id_;
};
}  // namespace

WebDriverServer::WebDriverServer(int port, const std::string& listen_ip,
                                 const HandleRequestCallback& callback,
                                 const std::string& address_cval_name)
    : handle_request_callback_(callback),
      server_address_(address_cval_name,
                      "Address to communicate with WebDriver.") {
  // Create http server
  std::unique_ptr<net::ServerSocket> server_socket =
      std::make_unique<net::TCPServerSocket>(nullptr, net::NetLogSource());
  server_socket->ListenWithAddressAndPort(listen_ip, port, 1 /*backlog*/);
  server_ = std::make_unique<net::HttpServer>(std::move(server_socket), this);
  net::IPEndPoint ip_addr;
  int result = server_->GetLocalInterfaceAddress(&ip_addr);
  if (result == net::OK) {
    LOG(INFO) << "Starting WebDriver server on port " << port;
    server_address_ = "http://" + ip_addr.ToString();
  } else {
    LOG(WARNING) << "Could not start WebDriver server";
    server_address_ = "<NOT RUNNING>";
  }
}

void WebDriverServer::OnConnect(int connection_id) {}

void WebDriverServer::OnHttpRequest(int connection_id,
                                    const net::HttpServerRequestInfo& info) {
  TRACE_EVENT0("cobalt::webdriver", "WebDriverServer::OnHttpRequest()");

  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  std::string path = info.path;
  size_t query_position = path.find("?");
  // Discard any URL variables from the path
  if (query_position != std::string::npos) {
    path.resize(query_position);
  }

  DLOG(INFO) << "Got request: " << path;
  // Create a new ResponseHandler that will send a response to this connection.
  std::unique_ptr<ResponseHandler> response_handler(
      new ResponseHandlerImpl(server_.get(), connection_id));

  std::unique_ptr<base::Value> parameters;
  HttpMethod method = StringToHttpMethod(info.method);
  if (method == kPost) {
    base::JSONReader reader;
    parameters = std::move(reader.ReadToValue(info.data));
    if (!parameters) {
      // Failed to parse request body as JSON.
      response_handler->MissingCommandParameters(reader.GetErrorMessage());
      return;
    }
  }

  // Call the HandleRequestCallback.
  handle_request_callback_.Run(StringToHttpMethod(info.method), path,
                               std::move(parameters),
                               std::move(response_handler));
}

}  // namespace webdriver
}  // namespace cobalt
