// Copyright 2013 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 "net/test/spawned_test_server/remote_test_server.h"

#include <limits>
#include <vector>

#include "base/base_paths.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "net/base/host_port_pair.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "net/test/spawned_test_server/remote_test_server_spawner_request.h"
#include "net/test/tcp_socket_proxy.h"
#include "starboard/types.h"
#include "url/gurl.h"

namespace net {

namespace {

// Please keep in sync with dictionary SERVER_TYPES in testserver.py
std::string GetServerTypeString(BaseTestServer::Type type) {
  switch (type) {
    case BaseTestServer::TYPE_FTP:
      return "ftp";
    case BaseTestServer::TYPE_HTTP:
    case BaseTestServer::TYPE_HTTPS:
      return "http";
    case BaseTestServer::TYPE_WS:
    case BaseTestServer::TYPE_WSS:
      return "ws";
    case BaseTestServer::TYPE_TCP_ECHO:
      return "tcpecho";
    case BaseTestServer::TYPE_UDP_ECHO:
      return "udpecho";
    default:
      NOTREACHED();
  }
  return std::string();
}

}  // namespace

RemoteTestServer::RemoteTestServer(Type type,
                                   const base::FilePath& document_root)
    : BaseTestServer(type), io_thread_("RemoteTestServer IO Thread") {
  if (!Init(document_root))
    NOTREACHED();
}

RemoteTestServer::RemoteTestServer(Type type,
                                   const SSLOptions& ssl_options,
                                   const base::FilePath& document_root)
    : BaseTestServer(type, ssl_options),
      io_thread_("RemoteTestServer IO Thread") {
  if (!Init(document_root))
    NOTREACHED();
}

RemoteTestServer::~RemoteTestServer() {
  Stop();
}

bool RemoteTestServer::StartInBackground() {
  DCHECK(!started());
  DCHECK(!start_request_);

  base::DictionaryValue arguments_dict;
  if (!GenerateArguments(&arguments_dict))
    return false;

  arguments_dict.Set("on-remote-server", std::make_unique<base::Value>());

  // Append the 'server-type' argument which is used by spawner server to
  // pass right server type to Python test server.
  arguments_dict.SetString("server-type", GetServerTypeString(type()));

  // If the server is expected to handle OCSP, it needs to know what port
  // number to write into the AIA urls. Initialize the ocsp proxy to
  // reserve a port, and pass it to the testserver so it can generate
  // certificates for the OCSP server valid for the proxied port. Note that
  // the test spawer may forward OCSP a second time, from the device to the
  // host.
  bool ocsp_server_enabled =
      type() == TYPE_HTTPS && (ssl_options().server_certificate ==
                                   SSLOptions::CERT_AUTO_AIA_INTERMEDIATE ||
                               !ssl_options().GetOCSPArgument().empty());
  if (ocsp_server_enabled) {
    ocsp_proxy_ = std::make_unique<TcpSocketProxy>(io_thread_.task_runner());
    bool initialized = ocsp_proxy_->Initialize();
    CHECK(initialized);
    arguments_dict.SetKey("ocsp-proxy-port-number",
                          base::Value(ocsp_proxy_->local_port()));
  }

  // Generate JSON-formatted argument string.
  std::string arguments_string;
  base::JSONWriter::Write(arguments_dict, &arguments_string);
  if (arguments_string.empty())
    return false;

  start_request_ = std::make_unique<RemoteTestServerSpawnerRequest>(
      io_thread_.task_runner(), config_.GetSpawnerUrl("start"),
      arguments_string);

  return true;
}

bool RemoteTestServer::BlockUntilStarted() {
  DCHECK(start_request_);

  std::string server_data_json;
  bool request_result = start_request_->WaitForCompletion(&server_data_json);
  start_request_.reset();
  if (!request_result)
    return false;

  // Parse server_data_json.
  if (server_data_json.empty() ||
      !SetAndParseServerData(server_data_json, &remote_port_)) {
    LOG(ERROR) << "Could not parse server_data: " << server_data_json;
    return false;
  }

  // If the server is not on localhost then start a proxy on localhost to
  // forward connections to the server.
  if (config_.address() != IPAddress::IPv4Localhost()) {
    test_server_proxy_ =
        std::make_unique<TcpSocketProxy>(io_thread_.task_runner());
    bool initialized = test_server_proxy_->Initialize();
    CHECK(initialized);
    test_server_proxy_->Start(IPEndPoint(config_.address(), remote_port_));

    SetPort(test_server_proxy_->local_port());
  } else {
    SetPort(remote_port_);
  }

  if (ocsp_proxy_) {
    const base::Value* ocsp_port_value = server_data().FindKey("ocsp_port");
    if (ocsp_port_value && ocsp_port_value->is_int()) {
      ocsp_proxy_->Start(
          IPEndPoint(config_.address(), ocsp_port_value->GetInt()));
    } else {
      LOG(WARNING) << "testserver.py didn't return ocsp_port.";
    }
  }

  return SetupWhenServerStarted();
}

bool RemoteTestServer::Stop() {
  DCHECK(!start_request_);

  if (remote_port_) {
    std::unique_ptr<RemoteTestServerSpawnerRequest> kill_request =
        std::make_unique<RemoteTestServerSpawnerRequest>(
            io_thread_.task_runner(),
            config_.GetSpawnerUrl(
                base::StringPrintf("kill?port=%d", remote_port_)),
            std::string());

    if (!kill_request->WaitForCompletion(nullptr))
      LOG(ERROR) << "Failed stopping RemoteTestServer";

    remote_port_ = 0;
  }

  CleanUpWhenStoppingServer();

  return true;
}

// On Android, the document root in the device is not the same as the document
// root in the host machine where the test server is launched. So prepend
// DIR_SOURCE_ROOT_FOR_TESTING here to get the actual path of document root on
// the Android device.
base::FilePath RemoteTestServer::GetDocumentRoot() const {
  base::FilePath src_dir;
  base::PathService::Get(base::DIR_TEST_DATA, &src_dir);
  return src_dir.Append(document_root());
}

bool RemoteTestServer::Init(const base::FilePath& document_root) {
  if (document_root.IsAbsolute())
    return false;

  config_ = RemoteTestServerConfig::Load();

  bool thread_started = io_thread_.StartWithOptions(
      base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
  CHECK(thread_started);

  // Unlike LocalTestServer, RemoteTestServer passes relative paths to the test
  // server. The test server fails on empty strings in some configurations.
  base::FilePath fixed_root = document_root;
  if (fixed_root.empty())
    fixed_root = base::FilePath(base::FilePath::kCurrentDirectory);
  SetResourcePath(fixed_root, base::FilePath()
                                  .AppendASCII("net")
                                  .AppendASCII("data")
                                  .AppendASCII("ssl")
                                  .AppendASCII("certificates"));
  return true;
}

}  // namespace net
