"""Base class for build recipes."""
import abc
import logging
import os
from pathlib import Path
import pprint
import six
from typing import Any, Dict, Optional

from helpers import accelerator_utils
from slave.accelerator import no_accelerator
from slave.step import clean_sync_step
from slave.step import git_clean_step
from slave.step import license_manager_step
from slave.step import make_clean_step
from slave.step import platform_info_step


LOGGER = logging.getLogger(__name__)

class BuildNameNotSupportedError(Exception):
  """Raised when a recipe does not support the given build_name."""


class BaseRecipe(six.with_metaclass(abc.ABCMeta, object)):
  """Base class for recipes."""

  def __init__(self,
               executor: 'Executor',
               eureka_root: str,
               enable_build_accelerator: bool=False,
               properties: Optional[Dict[str, Any]]=None,
               **kwargs):
    """Base constructor.

    Args:
      **kwargs: The kwargs to pass to individual steps.
    """
    LOGGER.info("Creating recipe %s", type(self))
    LOGGER.info("Properties: %s", pprint.pformat(properties))
    LOGGER.info("Eureka root: %s", eureka_root)
    self._eureka_root = Path(eureka_root)
    self._properties = properties or {}
    self._build_accelerator = (
        accelerator_utils.get_build_accelerator()
        if enable_build_accelerator else no_accelerator.NoAccelerator())
    self._executor = executor
    self._remote_lookup = None
    self._path_lookup = None
    self._fix_floats()
    self._skip_gclient = self._properties.get('skip_gclient', False)
    self._git_clean = self._properties.get('git_clean', False)
    self._make_clean = self.build_system == 'catabuilder'
    self._make_distclean = self._properties.get('make_distclean', False)
    self._manifest_branch = self._properties.get('manifest_branch')
    self._patch_project = self._properties.get('patch_project')
    self._env = self._properties.get('build_env', 'local')
    self._manifest_url = self._properties.get('manifest_url')
    self._check_android_license = (
        self._env != 'local' and kwargs.get('check_android_license', False))

    self._step_kwargs = kwargs.copy()
    self._step_kwargs['build_accelerator'] = self._build_accelerator
    self._step_kwargs["executor"] = executor
    self._step_kwargs["eureka_root"] = self._eureka_root
    self._step_kwargs["enable_build_accelerator"] = enable_build_accelerator
    self._step_kwargs["properties"] = properties

  @property
  def build_system(self):
    """Returns the name of current build system."""
    return self._properties.get('build_system', 'local')

  @property
  def buildername(self):
    """Returns the buildername of the current build."""
    return self._properties.get('buildername')

  def get_setup_steps(self):
    """Returns a list of all steps that should be executed as part of setup.

    Returns:
      List of slave.base_step.BaseStep commands to be executed.
    """
    setup_steps = []
    setup_steps.append(
        platform_info_step.PlatformInfoStep(
            directory='', **self._step_kwargs))

    if not self._skip_gclient:
      setup_steps.append(
          clean_sync_step.GclientSyncStep(
              directory='', **self._step_kwargs))

    if self._check_android_license:
      setup_steps.append(license_manager_step.AndroidSdkLicenseCheckAccept(
          directory='', **self._step_kwargs))

    setup_steps.extend(
        self. _get_build_accelerator().setup_steps(self._step_kwargs))

    if self._make_clean:
      setup_steps += self.get_clean_steps()

    if self._make_distclean:
      setup_steps.append(
          make_clean_step.MakeDistCleanStep(**self._step_kwargs))

    if self._git_clean:
      setup_steps.append(
          git_clean_step.GitCleanStep(**self._step_kwargs))

    return setup_steps

  def _get_build_accelerator(self):
    return self._build_accelerator

  def get_teardown_steps(self):
    """Returns a list of all steps that should be executed as part of teardown.

    Returns:
      List of slave.base_step.BaseStep commands to be executed.
    """
    return self._get_build_accelerator().tear_down_steps(self._step_kwargs)

  @property
  def build_number(self):
    """Construct BUILD_NUMBER string in unified way between all systems.

    This property is matching the same property in the BaseStep, should be
    altered together.

    Returns:
      CL number (from 'issue' porperty) for CQ, buildset number for CB or 0
    """
    return str(self._properties.get(
        'issue', self._properties.get('buildset', '0')))

  @abc.abstractmethod
  def get_steps(self):
    """Builds a list of all steps that should be executed by this recipe.

    Returns:
      List of slave.base_step.BaseStep commands to be executed.
    """
    return []

  def get_clean_steps(self):
    """Builds a list of all clean steps that should be executed by this recipe.

    Returns:
      List of slave.base_step.BaseStep commands to be executed.
    """
    return []

  def _fix_floats(self):
    """Buildbucket is enforcing floats, but we want ints."""
    for key, value in self._properties.items():
      if isinstance(value, float):
        self._properties[key] = int(value)

  def _getcwd(self):
    """Helper function to make it easy to mock os.getcwd() for tests."""
    return os.getcwd()
