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

#include "base/command_line.h"
#include "base/environment.h"
#include "base/files/file_util.h"
#include "base/path_service.h"
#include "base/rand_util.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
#include "net/base/ip_address.h"
#include "net/base/net_errors.h"
#include "net/log/net_log_source.h"
#include "net/socket/tcp_server_socket.h"
#include "net/test/python_utils.h"

const uint16_t kMinPort = 17000;
const uint16_t kPortRangeSize = 1000;

// Widevine license server configuration files.
const base::FilePath::CharType kKeysFileName[] =
    FILE_PATH_LITERAL("keys.dat");
const base::FilePath::CharType kPoliciesFileName[] =
    FILE_PATH_LITERAL("policies.dat");
const base::FilePath::CharType kProfilesFileName[] =
    FILE_PATH_LITERAL("profiles.dat");

// License server configuration files directory name relative to root.
const base::FilePath::CharType kLicenseServerConfigDirName[] =
    FILE_PATH_LITERAL("config");

WVTestLicenseServerConfig::WVTestLicenseServerConfig() {
}

WVTestLicenseServerConfig::~WVTestLicenseServerConfig() {
}

bool WVTestLicenseServerConfig::GetServerCommandLine(
    base::CommandLine* command_line) {
  if (!GetPythonCommand(command_line)) {
    LOG(ERROR) << "Could not get Python runtime command.";
    return false;
  }

  base::FilePath license_server_path;
  GetLicenseServerPath(&license_server_path);
  if (!base::PathExists(license_server_path)) {
    LOG(WARNING) << "Missing license server file at "
                 << license_server_path.value();
    return false;
  }

  base::FilePath server_root;
  GetLicenseServerRootPath(&server_root);
  base::FilePath config_path = server_root.Append(kLicenseServerConfigDirName);

  if (!base::PathExists(config_path.Append(kKeysFileName)) ||
      !base::PathExists(config_path.Append(kPoliciesFileName)) ||
      !base::PathExists(config_path.Append(kProfilesFileName))) {
    LOG(WARNING) << "Missing license server configuration files at "
                 << config_path;
    return false;
  }

  if (!SelectServerPort())
    return false;

  // Needed to dynamically load .so libraries used by license server.
  // TODO(shadi): Remove need to set env variable once b/12932983 is fixed.
#if defined(OS_LINUX) || defined(OS_CHROMEOS)
  std::unique_ptr<base::Environment> env(base::Environment::Create());
  const char kLibraryPathEnvVarName[] = "LD_LIBRARY_PATH";
  std::string library_paths(license_server_path.DirName().value());
  std::string old_path;
  if (env->GetVar(kLibraryPathEnvVarName, &old_path))
    library_paths.append(":").append(old_path);
  env->SetVar(kLibraryPathEnvVarName, library_paths);
#endif  // defined(OS_LINUX) || defined(OS_CHROMEOS)

  // Since it is a Python command line, we need to AppendArg instead of
  // AppendSwitch so that the arguments are passed to the Python server instead
  // of Python engine.
  command_line->AppendArgPath(license_server_path);
  command_line->AppendArg("-k");
  command_line->AppendArgPath(config_path.Append(kKeysFileName));
  command_line->AppendArg("-o");
  command_line->AppendArgPath(config_path.Append(kPoliciesFileName));
  command_line->AppendArg("-r");
  command_line->AppendArgPath(config_path.Append(kProfilesFileName));
  command_line->AppendArg(base::StringPrintf("--port=%u", port_));
  return true;
}

base::Optional<base::EnvironmentMap>
WVTestLicenseServerConfig::GetServerEnvironment() {
  // Add the Python protocol buffers files directory to Python path.
  base::FilePath pyproto_dir;
  if (!GetPyProtoPath(&pyproto_dir)) {
    LOG(WARNING) << "Cannot find pyproto directory required by license server.";
    return base::nullopt;
  }

  base::EnvironmentMap map;
  SetPythonPathInEnvironment({pyproto_dir}, &map);
  return map;
}

bool WVTestLicenseServerConfig::SelectServerPort() {
  // Try all ports within the range of kMinPort to (kMinPort + kPortRangeSize)
  // Instead of starting from kMinPort, use a random port within that range.
  uint16_t start_seed = base::RandInt(0, kPortRangeSize);
  uint16_t try_port = 0;
  for (uint16_t i = 0; i < kPortRangeSize; ++i) {
    try_port = kMinPort + (start_seed + i) % kPortRangeSize;
    net::NetLogSource source;
    net::TCPServerSocket sock(NULL, source);
    if (sock.Listen(net::IPEndPoint(net::IPAddress::IPv4Localhost(), try_port),
                    1) == net::OK) {
      port_ = try_port;
      return true;
    }
  }
  LOG(WARNING) << "Could not find an open port in the range of " << kMinPort
               << " to " << kMinPort + kPortRangeSize;
  return false;
}

bool WVTestLicenseServerConfig::IsPlatformSupported() {
#if (defined(OS_LINUX) || defined(OS_CHROMEOS)) && defined(ARCH_CPU_X86_64)
  return true;
#else
  return false;
#endif // (defined(OS_LINUX) || defined(OS_CHROMEOS)) && defined(ARCH_CPU_X86_64)
}

std::string WVTestLicenseServerConfig::GetServerURL() {
  return base::StringPrintf("http://localhost:%u/license_server", port_);
}

void WVTestLicenseServerConfig::GetLicenseServerPath(base::FilePath *path) {
  base::FilePath server_root;
  GetLicenseServerRootPath(&server_root);
  // Platform-specific license server binary path relative to root.
  *path =
#if defined(OS_LINUX) || defined(OS_CHROMEOS)
      server_root.Append(FILE_PATH_LITERAL("linux"))
          .Append(FILE_PATH_LITERAL("license_server.py"));
#else
    server_root.Append(FILE_PATH_LITERAL("unsupported_platform"));
#endif  // defined(OS_LINUX) || defined(OS_CHROMEOS)
}

void WVTestLicenseServerConfig::GetLicenseServerRootPath(
    base::FilePath* path) {
  base::FilePath source_root;
  base::PathService::Get(base::DIR_SOURCE_ROOT, &source_root);
  *path = source_root.Append(FILE_PATH_LITERAL("third_party"))
                     .Append(FILE_PATH_LITERAL("widevine"))
                     .Append(FILE_PATH_LITERAL("test"))
                     .Append(FILE_PATH_LITERAL("license_server"));
}
