# -*- coding: utf-8 -*-
# Copyright 2018 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Choose the profile for a board that has been or is being setup."""

from __future__ import print_function

import functools
import os
import sys

import six

from chromite.lib import commandline
from chromite.lib import cros_build_lib
from chromite.lib import cros_logging as logging
from chromite.lib import osutils
from chromite.lib import sysroot_lib


assert sys.version_info >= (3, 6), 'This module requires Python 3.6+'


# Default value constants.
_DEFAULT_PROFILE = 'base'


def PathPrefixDecorator(f):
  """Add a prefix to the path or paths returned by the decorated function.

  Will not prepend the prefix if the path already starts with the prefix, so the
  decorator may be applied to functions that have mixed sources that may
  or may not already have applied them. This is especially useful for allowing
  tests and CLI args a little more leniency in how paths are provided.
  """
  @functools.wraps(f)
  def wrapper(*args, **kwargs):
    result = f(*args, **kwargs)
    prefix = PathPrefixDecorator.prefix

    if not prefix or not result:
      # Nothing to do.
      return result
    elif not isinstance(result, six.string_types):
      # Transform each path in the collection.
      new_result = []
      for path in result:
        prefixed_path = os.path.join(prefix, path.lstrip(os.sep))
        new_result.append(path if path.startswith(prefix) else prefixed_path)

      return new_result
    elif not result.startswith(prefix):
      # Add the prefix.
      return os.path.join(prefix, result.lstrip(os.sep))

    # An already prefixed path.
    return result

  return wrapper

PathPrefixDecorator.prefix = None


class Error(Exception):
  """Base error for custom exceptions in this script."""


class InvalidArgumentsError(Error):
  """Invalid arguments."""


class MakeProfileIsNotLinkError(Error):
  """The make profile exists but is not a link."""


class ProfileDirectoryNotFoundError(Error):
  """Unable to find the profile directory."""


def ChooseProfile(board, profile):
  """Make the link to choose the profile, print relevant warnings.

  Args:
    board: Board - the board being used.
    profile: Profile - the profile being used.

  Raises:
    OSError when the board's make_profile path exists and is not a link.
  """
  if not os.path.isfile(os.path.join(profile.directory, 'parent')):
    logging.warning("Portage profile directory %s has no 'parent' file. "
                    'This likely means your profile directory is invalid and '
                    'build_packages will fail.', profile.directory)

  current_profile = None
  if os.path.exists(board.make_profile):
    # Only try to read if it exists; we only want it to raise an error when the
    # path exists and is not a link.
    try:
      current_profile = os.readlink(board.make_profile)
    except OSError:
      raise MakeProfileIsNotLinkError('%s is not a link.' % board.make_profile)

  if current_profile == profile.directory:
    # The existing link is what we were going to make, so nothing to do.
    return
  elif current_profile is not None:
    # It exists and is changing, emit warning.
    fmt = {'board': board.board_variant, 'profile': profile.name}
    msg = ('You are switching profiles for a board that is already setup. This '
           'can cause trouble for Portage. If you experience problems with '
           'build_packages you may need to run:\n'
           "\t'setup_board --board %(board)s --force --profile %(profile)s'\n"
           '\nAlternatively, you can correct the dependency graph by using '
           "'emerge-%(board)s -c' or 'emerge-%(board)s -C <ebuild>'.")
    logging.warning(msg, fmt)

  # Make the symlink, overwrites existing link if one already exists.
  osutils.SafeSymlink(profile.directory, board.make_profile, sudo=True)

  # Update the profile override value.
  if profile.override:
    board.profile_override = profile.override


class Profile(object):
  """Simple data container class for the profile data."""
  def __init__(self, name, directory, override):
    self.name = name
    self._directory = directory
    self.override = override

  @property
  @PathPrefixDecorator
  def directory(self):
    return self._directory


def _GetProfile(opts, board):
  """Get the profile list."""
  # Determine the override value - which profile is being selected.
  override = opts.profile if opts.profile else board.profile_override

  profile = _DEFAULT_PROFILE
  profile_directory = None

  if override and os.path.exists(override):
    profile_directory = os.path.abspath(override)
    profile = os.path.basename(profile_directory)
  elif override:
    profile = override

  if profile_directory is None:
    # Build profile directories in reverse order so we can search from most to
    # least specific.
    profile_dirs = ['%s/profiles/%s' % (overlay, profile) for overlay in
                    reversed(board.overlays)]

    for profile_dir in profile_dirs:
      if os.path.isdir(profile_dir):
        profile_directory = profile_dir
        break
    else:
      searched = ', '.join(profile_dirs)
      raise ProfileDirectoryNotFoundError(
          'Profile directory not found, searched in (%s).' % searched)

  return Profile(profile, profile_directory, override)


class Board(object):
  """Manage the board arguments and configs."""

  # Files located on the board.
  MAKE_PROFILE = '%(board_root)s/etc/portage/make.profile'

  def __init__(self, board=None, variant=None, board_root=None):
    """Board constructor.

    board [+ variant] is given preference when both board and board_root are
    provided.

    Preconditions:
      Either board and build_root are not None, or board_root is not None.
        With board + build_root [+ variant] we can construct the board root.
        With the board root we can have the board[_variant] directory.

    Args:
      board: str|None - The board name.
      variant: str|None - The variant name.
      board_root: str|None - The boards fully qualified build directory path.
    """
    if not board and not board_root:
      # Enforce preconditions.
      raise InvalidArgumentsError('Either board or board_root must be '
                                  'provided.')
    elif board:
      # The board and variant can be specified separately, or can both be
      # contained in the board name, separated by an underscore.
      board_split = board.split('_')
      variant_default = variant

      self._board_root = None
    else:
      self._board_root = os.path.normpath(board_root)

      board_split = os.path.basename(self._board_root).split('_')
      variant_default = None

    self.board = board_split.pop(0)
    self.variant = board_split.pop(0) if board_split else variant_default

    if self.variant:
      self.board_variant = '%s_%s' % (self.board, self.variant)
    else:
      self.board_variant = self.board

    self.make_profile = self.MAKE_PROFILE % {'board_root': self.root}
    # This must come after the arguments required to build each variant of the
    # build root have been processed.
    self._sysroot_config = sysroot_lib.Sysroot(self.root)

  @property
  @PathPrefixDecorator
  def root(self):
    if self._board_root:
      return self._board_root

    return os.path.join(cros_build_lib.GetSysroot(self.board_variant))

  @property
  @PathPrefixDecorator
  def overlays(self):
    return self._sysroot_config.GetStandardField(
        sysroot_lib.STANDARD_FIELD_BOARD_OVERLAY).split()

  @property
  def profile_override(self):
    return self._sysroot_config.GetCachedField('PROFILE_OVERRIDE')

  @profile_override.setter
  def profile_override(self, value):
    self._sysroot_config.SetCachedField('PROFILE_OVERRIDE', value)


def _GetBoard(opts):
  """Factory method to build a Board from the parsed CLI arguments."""
  return Board(board=opts.board, variant=opts.variant,
               board_root=opts.board_root)


def GetParser():
  """ArgumentParser builder and argument definitions."""
  parser = commandline.ArgumentParser(description=__doc__)
  parser.add_argument('-b', '--board',
                      default=os.environ.get('DEFAULT_BOARD'),
                      help='The name of the board to set up.')
  parser.add_argument('-r', '--board-root',
                      type='path',
                      help='Board root where the profile should be created.')
  parser.add_argument('-p', '--profile',
                      help='The portage configuration profile to use.')
  parser.add_argument('--variant', help='Board variant.')

  group = parser.add_argument_group('Advanced options')
  group.add_argument('--filesystem-prefix',
                     type='path',
                     help='Force filesystem accesses to be prefixed by the '
                          'given path.')
  return parser


def ParseArgs(argv):
  """Parse and validate the arguments."""
  parser = GetParser()
  opts = parser.parse_args(argv)

  # See Board.__init__ Preconditions.
  board_valid = opts.board is not None
  board_root_valid = opts.board_root and os.path.exists(opts.board_root)

  if not board_valid and not board_root_valid:
    parser.error('Either board or board_root must be provided.')

  PathPrefixDecorator.prefix = opts.filesystem_prefix
  del opts.filesystem_prefix

  opts.Freeze()
  return opts


def main(argv):
  # Parse arguments.
  opts = ParseArgs(argv)

  # Build and validate the board and profile.
  board = _GetBoard(opts)

  if not os.path.exists(board.root):
    cros_build_lib.Die('The board has not been setup, please run setup_board '
                       'first.')

  try:
    profile = _GetProfile(opts, board)
  except ProfileDirectoryNotFoundError as e:
    cros_build_lib.Die(e)

  # Change the profile to the selected.
  logging.info('Selecting profile: %s for %s', profile.directory, board.root)

  try:
    ChooseProfile(board, profile)
  except MakeProfileIsNotLinkError as e:
    cros_build_lib.Die(e)
