// 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::UTF16ToUTF8(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;
}
