# Copyright 2015 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.

"""
GN-related configuration functions, e.g., to produce a Config object from a GN
args.gn file).
"""


import ast
import os.path
import re

from .config import Config


def BuildDirectoryForConfig(config, src_root):
  """
  Returns the build directory for the given configuration.
  """
  subdir = ""
  if config.target_os == Config.OS_ANDROID:
    subdir += "android_"
    if config.target_cpu != Config.ARCH_ARM:
      subdir += config.target_cpu + "_"
  elif config.target_os == Config.OS_FNL:
    subdir += "fnl_"
  elif config.target_os == Config.OS_IOS:
    subdir += "ios_"
  if config.is_simulator:
    subdir += "sim_"
  if config.is_official_build:
    subdir += "Official"
  elif config.is_debug:
    subdir += "Debug"
  else:
    subdir += "Release"
  if config.sanitizer == Config.SANITIZER_ASAN:
    subdir += "_asan"
  if not(config.is_debug) and config.dcheck_always_on:
    subdir += "_dcheck"
  return os.path.join(src_root, "out", subdir)


def GNArgsForConfig(config):
  """
  Return the arguments for gn for the given configuration. This function returns
  a dictionary with boolean values as boolean.
  """
  gn_args = {}

  gn_args["is_debug"] = bool(config.is_debug)
  gn_args["is_official_build"] = bool(config.is_official_build)
  gn_args["is_asan"] = config.sanitizer == Config.SANITIZER_ASAN

  if config.is_clang is not None:
    gn_args["is_clang"] = bool(config.is_clang)
  else:
    gn_args["is_clang"] = config.target_os not in (Config.OS_ANDROID,
                                                   Config.OS_FNL,
                                                   Config.OS_WINDOWS)

  if config.values.get("use_goma"):
    gn_args["use_goma"] = True
    gn_args["goma_dir"] = config.values["goma_dir"]
  else:
    gn_args["use_goma"] = False

  gn_args["dcheck_always_on"] = config.dcheck_always_on

  if config.target_os == Config.OS_ANDROID:
    gn_args["target_os"] = "android"
  elif config.target_os == Config.OS_FNL:
    gn_args["target_os"] = "fnl"
    gn_args["use_ozone"] = True
    gn_args["target_sysroot"] = config.values.get("target_sysroot", "")
    gn_args["toolchain_prefix"] = config.values.get("toolchain_prefix", "")
  elif config.target_os == Config.OS_IOS:
    gn_args["target_os"] = "ios"
    gn_args["ios_deployment_target"] = "7.0"
    gn_args["clang_use_chrome_plugins"] = False
    gn_args["use_ios_simulator"] = config.is_simulator
  elif config.target_os == Config.OS_LINUX:
    pass

  gn_args["target_cpu"] = config.target_cpu

  if "use_nacl" in config.values:
    gn_args["mojo_use_nacl"] = config.values.get("use_nacl", False)

  if "mojo_use_go" in config.values:
    gn_args["mojo_use_go"] = config.values.get("mojo_use_go", False)
    if gn_args["mojo_use_go"]:
      gn_args["go_build_tool"] = config.values.get("go_build_tool")

  gn_args["dart_boringssl_path"] = config.values.get("boringssl_path", "")

  extra_args = config.values.get("gn_args")
  if extra_args:
    for arg in extra_args.split():
      (name, val) = arg.split('=')
      gn_args[name] = val

  return gn_args


def CommandLineForGNArgs(gn_args):
  """
  Returns the list of gn arguments to use with the gn command line.
  """
  def _ToCommandLine(key, value):
    if type(value) is bool:
      return "%s=%s" % (key, "true" if value else "false")
    return "%s=\"%s\"" % (key, value)
  return [_ToCommandLine(x, y) for x, y in gn_args.iteritems()]


def ConfigForGNArgs(args):
  """
  Return the Config object for the given gn arguments. This function takes a
  dictionary with boolean values as boolean.
  """
  config_args = {}
  config_args["is_debug"] = args.get("is_debug", True)
  config_args["is_official_build"] = args.get("is_official_build", False)
  config_args["sanitizer"] = (
      Config.SANITIZER_ASAN if args.get("is_asan") else None)
  config_args["is_clang"] = args.get("is_clang", False)
  config_args["use_goma"] = args.get("use_goma", False)
  if config_args["use_goma"]:
    config_args["goma_dir"] = args.get("goma_dir")
  config_args["use_nacl"] = args.get("mojo_use_nacl", False)
  config_args["mojo_use_go"] = args.get("mojo_use_go", False)
  if config_args["mojo_use_go"]:
    config_args["go_build_tool"] = args.get("go_build_tool")
  config_args["target_os"] = args.get("target_os")
  config_args["target_cpu"] = args.get("target_cpu")
  config_args["dcheck_always_on"] = args.get("dcheck_always_on")
  config_args["is_simulator"] = args.get("use_ios_simulator", False)
  if "target_sysroot" in args:
    config_args["target_sysroot"] = args.get("target_sysroot")
  if "toolchain_prefix" in args:
    config_args["toolchain_prefix"] = args.get("toolchain_prefix")
  config_args["boringssl_path"] = args.get("dart_boringssl_path")
  return Config(**config_args)


def ParseGNConfig(build_dir):
  """
  Parse the gn config file present in |build_dir|. This function returns a
  dictionary with boolean values as boolean.
  """
  TRANSLATIONS = {
      "true": "True",
      "false": "False",
  }
  gn_file = os.path.join(build_dir, "args.gn")
  values = {}
  with open(gn_file, "r") as f:
    for line in f.readlines():
      line = re.sub("\s*#.*", "", line)
      result = re.match("^\s*(\w+)\s*=\s*(.*)\s*$", line)
      if result:
        key = result.group(1)
        value = result.group(2)
        values[key] = ast.literal_eval(TRANSLATIONS.get(value, value))
  return values
