"""Build steps to run GN commands on eureka internal."""

from __future__ import absolute_import
import os

from helpers import gn_utils
from slave.step import shell_step


class GnGenStep(shell_step.ShellStep):
  """Build step class to call gn gen as a recipe step."""

  def __init__(self, build_args_product, build_args, out_dir, cwd, *args,
               **kwargs):
    self._build_args_product = build_args_product
    self._build_args = build_args
    self._out_dir = out_dir
    super().__init__(name='gn_gen', cwd=cwd, *args, **kwargs)

  def get_commands(self):
    """Returns which commands to be run.

    Can be overridden by a subclass.

    Returns:
      List of ShellCommand objects to execute.
    """
    gn_import = (
        'import("//chromecast/internal/build/args/product/{}.gn")').format(
            self._build_args_product)
    build_args = self._build_args + self.build_accelerator.gn_flags
    args_str = '{} {}'.format(gn_import, ' '.join(build_args))
    cmd_list = [
        gn_utils.GN_BINARY, 'gen', self._out_dir, '--root=chromium/src',
        '--check', '--args={}'.format(args_str)
    ]
    return [self.ShellCommand(cmd_list, validator=self._validator)]


class GnArgsStep(shell_step.ShellStep):
  """Build step class to call gn args as a recipe step."""

  def __init__(self, out_dir, cwd, *args, **kwargs):
    cmd_list = [
        gn_utils.GN_BINARY,
        'args',
        out_dir,
        '--root=chromium/src',
        '--list',
        '--short',
        '--overrides-only',
    ]
    super().__init__(command=cmd_list, name='gn_list', cwd=cwd, *args, **kwargs)


class GnGenCompilationDBStep(shell_step.ShellStep):
  """Build step class to call gn gen as a recipe step."""

  def __init__(self, out_dir, cwd, build_args_product, target_name, *args,
               **kwargs):
    self._build_args_product = build_args_product
    self._target_name = target_name
    self._out_dir = out_dir
    self._build_args = [
        'use_rbe=false', 'use_goma=false', 'clang_use_chrome_plugins=false'
    ]
    super().__init__(name='gn_gen_compdb', cwd=cwd, *args, **kwargs)

  def get_compdb_file_location(self):
    return os.path.join(self._out_dir, 'compile_commands.json')

  def get_commands(self):
    """Returns which commands to be run.

    Can be overridden by a subclass.

    Returns:
      List of ShellCommand objects to execute.
    """
    commands = []

    # Re-generate the GN arguments for the product in order to disable build
    # accelerators and clang_use_chrome_plugins. Otherwise, the Kythe analyzer
    # will err as it does not have context of these compiler directives.
    gn_import = (
        'import("//chromecast/internal/build/args/product/{}.gn")').format(
            self._build_args_product)
    args_str = '{} {}'.format(gn_import, ' '.join(self._build_args))
    args_with_acceleration_disabled = '--args={}'.format(args_str)

    # Generate the compdb (compile_commands.json) file.
    compile_commands_flag = '--export-compile-commands={}'.format(
        self._target_name)

    gen_compdb_command = [
        gn_utils.GN_BINARY,
        'gen',
        self._out_dir,
        '--root=chromium/src',
        args_with_acceleration_disabled,
        compile_commands_flag,
    ]
    commands.append(
        self.ShellCommand(gen_compdb_command, validator=self._validator))

    return commands
