// Copyright (c) 2011 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/python_utils.h"

#include <memory>

#include "base/base_paths.h"
#include "base/command_line.h"
#include "base/environment.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/process/launch.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"

#if defined(OS_MACOSX)
#include "base/mac/foundation_util.h"
#endif

const char kPythonPathEnv[] = "PYTHONPATH";
const char kVPythonClearPathEnv[] = "VPYTHON_CLEAR_PYTHONPATH";

void ClearPythonPath() {
  std::unique_ptr<base::Environment> env(base::Environment::Create());
  env->UnSetVar(kPythonPathEnv);

  // vpython has instructions on BuildBot (not swarming or LUCI) to clear
  // PYTHONPATH on invocation. Since we are clearing and manipulating it
  // ourselves, we don't want vpython to throw out our hard work.
  env->UnSetVar(kVPythonClearPathEnv);
}

void AppendToPythonPath(const base::FilePath& dir) {
  std::unique_ptr<base::Environment> env(base::Environment::Create());
  std::string old_path;
  std::string dir_path;
#if defined(OS_WIN)
  dir_path = base::WideToUTF8(dir.value());
#elif defined(OS_POSIX)
  dir_path = dir.value();
#endif
  if (!env->GetVar(kPythonPathEnv, &old_path)) {
    env->SetVar(kPythonPathEnv, dir_path.c_str());
  } else if (old_path.find(dir_path) == std::string::npos) {
    std::string new_path(old_path);
#if defined(OS_WIN)
    new_path.append(";");
#elif defined(OS_POSIX)
    new_path.append(":");
#endif
    new_path.append(dir_path.c_str());
    env->SetVar(kPythonPathEnv, new_path);
  }
}

bool GetPyProtoPath(base::FilePath* dir) {
  // Locate the Python code generated by the protocol buffers compiler.
  base::FilePath generated_code_dir;
  if (!base::PathService::Get(base::DIR_EXE, &generated_code_dir)) {
    LOG(ERROR) << "Can't find " << generated_code_dir.value();
    return false;
  }

#if defined(OS_MACOSX)
  if (base::mac::AmIBundled())
    generated_code_dir = generated_code_dir.DirName().DirName().DirName();
#endif

  // Used for GYP. TODO(jam): remove after GN conversion.
  const base::FilePath kPyProto(FILE_PATH_LITERAL("pyproto"));
  if (base::DirectoryExists(generated_code_dir.Append(kPyProto))) {
    *dir = generated_code_dir.Append(kPyProto);
    return true;
  }

  // Used for GN.
  const base::FilePath kGen(FILE_PATH_LITERAL("gen"));
  if (base::DirectoryExists(generated_code_dir.Append(kGen))) {
    *dir = generated_code_dir.Append(kGen);
    return true;
  }

  return false;
}

bool GetPythonCommand(base::CommandLine* python_cmd) {
  DCHECK(python_cmd);

// Use vpython to pick up src.git's vpython VirtualEnv spec.
#if defined(OS_WIN)
  python_cmd->SetProgram(base::FilePath(FILE_PATH_LITERAL("vpython.bat")));
#else
  python_cmd->SetProgram(base::FilePath(FILE_PATH_LITERAL("vpython")));
#endif

  // Launch python in unbuffered mode, so that python output doesn't mix with
  // gtest output in buildbot log files. See http://crbug.com/147368.
  python_cmd->AppendArg("-u");

  return true;
}
