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

"""Common brick related utilities."""

from __future__ import print_function

import json
import os

from chromite.lib import osutils
from chromite.lib import portage_util
from chromite.lib import workspace_lib

_DEFAULT_LAYOUT_CONF = {'profile-formats': 'portage-2',
                        'thin-manifests': 'true',
                        'use-manifests': 'true'}

_CONFIG_JSON = 'config.json'

_IGNORED_OVERLAYS = ('portage-stable', 'chromiumos', 'eclass-overlay')


class BrickCreationFailed(Exception):
  """The brick creation failed."""


class BrickNotFound(Exception):
  """The brick does not exist."""


class BrickFeatureNotSupported(Exception):
  """Attempted feature not supported for this brick."""


class Brick(object):
  """Encapsulates the interaction with a brick."""

  def __init__(self, brick_loc, initial_config=None, allow_legacy=True):
    """Instantiates a brick object.

    Args:
      brick_loc: brick locator. This can be a relative path to CWD, an absolute
        path, a public board name prefix with 'board:' or a relative path to the
        root of the workspace, prefixed with '//').
      initial_config: The initial configuration as a python dictionary.
        If not None, creates a brick with this configuration.
      allow_legacy: Allow board overlays, simulating a basic read-only config.
        Ignored if |initial_config| is not None.

    Raises:
      ValueError: If |brick_loc| is invalid.
      LocatorNotResolved: |brick_loc| is valid but could not be resolved.
      BrickNotFound: If |brick_loc| does not point to a brick and no initial
        config was provided.
      BrickCreationFailed: when the brick could not be created successfully.
    """
    if workspace_lib.IsLocator(brick_loc):
      self.brick_dir = workspace_lib.LocatorToPath(brick_loc)
      self.brick_locator = brick_loc
    else:
      self.brick_dir = brick_loc
      self.brick_locator = workspace_lib.PathToLocator(brick_loc)

    self.config = None
    self.legacy = False
    config_json = os.path.join(self.brick_dir, _CONFIG_JSON)

    if not os.path.exists(config_json):
      if initial_config:
        if os.path.exists(self.brick_dir):
          raise BrickCreationFailed('directory %s already exists.'
                                    % self.brick_dir)
        success = False
        try:
          self.UpdateConfig(initial_config)
          success = True
        except BrickNotFound as e:
          # If BrickNotFound was raised, the dependencies contain a missing
          # brick.
          raise BrickCreationFailed('dependency not found %s' % e)
        finally:
          if not success:
            # If the brick creation failed for any reason, cleanup the partially
            # created brick.
            osutils.RmDir(self.brick_dir, ignore_missing=True)

      elif allow_legacy:
        self.legacy = True
        try:
          masters = self._ReadLayoutConf().get('masters')
          masters_list = masters.split() if masters else []

          # Keep general Chromium OS overlays out of this list as they are
          # handled separately by the build system.
          deps = ['board:' + d for d in masters_list
                  if d not in _IGNORED_OVERLAYS]
          self.config = {'name': self._ReadLayoutConf()['repo-name'],
                         'dependencies': deps}
        except (IOError, KeyError):
          pass

      if self.config is None:
        raise BrickNotFound('Brick not found at %s' % self.brick_dir)
    elif initial_config is None:
      self.config = json.loads(osutils.ReadFile(config_json))
    else:
      raise BrickCreationFailed('brick %s already exists.' % self.brick_dir)

    self.friendly_name = None
    if not self.legacy:
      self.friendly_name = workspace_lib.LocatorToFriendlyName(
          self.brick_locator)

  def _LayoutConfPath(self):
    """Returns the path to the layout.conf file."""
    return os.path.join(self.OverlayDir(), 'metadata', 'layout.conf')

  def _WriteLayoutConf(self, content):
    """Writes layout.conf.

    Sets unset fields to a sensible default and write |content| in layout.conf
    in the right format.

    Args:
      content: dictionary containing the set fields in layout.conf.
    """
    for k, v in _DEFAULT_LAYOUT_CONF.iteritems():
      content.setdefault(k, v)

    content_str = ''.join(['%s = %s\n' % (k, v)
                           for k, v in content.iteritems()])
    osutils.WriteFile(self._LayoutConfPath(), content_str, makedirs=True)

  def _ReadLayoutConf(self):
    """Returns the content of layout.conf as a Python dictionary."""
    def ParseConfLine(line):
      k, _, v = line.partition('=')
      return k.strip(), v.strip() or None

    content_str = osutils.ReadFile(self._LayoutConfPath())
    return dict(ParseConfLine(line) for line in content_str.splitlines())

  def _WriteParents(self, parents):
    """Writes the parents profile.

    Args:
      parents: list of overlay names
    """
    if self.legacy:
      raise BrickFeatureNotSupported()

    osutils.WriteFile(os.path.join(self.OverlayDir(), 'profiles', 'base',
                                   'parent'),
                      ''.join([p + '\n' for p in parents]), makedirs=True)

  def UpdateConfig(self, config, regenerate=True):
    """Updates the brick's configuration.

    Write the json representation of |config| in config.json.
    If |regenerate| is true, regenerate the portage configuration files in
    this brick to match the new config.json.

    Args:
      config: brick configuration as a python dict
      regenerate: if True, regenerate autogenerated brick files
    """
    if self.legacy:
      raise BrickFeatureNotSupported(
          'Cannot update configuration of legacy brick %s' % self.brick_dir)

    self.config = config
    # All objects must be unambiguously referenced. Normalize all the
    # dependencies according to the workspace.
    self.config['dependencies'] = [d if workspace_lib.IsLocator(d)
                                   else workspace_lib.PathToLocator(d)
                                   for d in self.config.get('dependencies', [])]

    formatted_config = json.dumps(config, sort_keys=True, indent=4,
                                  separators=(',', ': '))
    osutils.WriteFile(os.path.join(self.brick_dir, _CONFIG_JSON),
                      formatted_config, makedirs=True)

    if regenerate:
      self.GeneratePortageConfig()

  def GeneratePortageConfig(self):
    """Generates all autogenerated brick files."""
    # We don't generate anything in legacy brick so everything is up-to-date.
    if self.legacy:
      return

    deps = [b.config['name'] for b in self.Dependencies()]

    self._WriteLayoutConf(
        {'masters': ' '.join(
            ['eclass-overlay', 'portage-stable', 'chromiumos'] + deps),
         'repo-name': self.config['name']})

    parents = self.config.get('experimental_profiles',
                              [m + ':base' for m in deps])
    self._WriteParents(parents)

  def Dependencies(self):
    """Returns the dependent bricks."""
    return [Brick(d) for d in self.config.get('dependencies', [])]

  def Inherits(self, brick_name):
    """Checks whether this brick contains |brick_name|.

    Args:
      brick_name: The name of the brick to check containment.

    Returns:
      Whether |brick_name| is contained in this brick.
    """
    return brick_name in [b.config['name'] for b in self.BrickStack()]

  def MainPackages(self):
    """Returns the brick's main package(s).

    This finds the 'main_package' property.  It nevertheless returns a (single
    element) list as it is easier to work with.

    Returns:
      A list of main packages; empty if no main package configured.
    """
    main_package = self.config.get('main_package')
    return [main_package] if main_package else []

  def OverlayDir(self):
    """Returns the brick's overlay directory."""
    if self.legacy:
      return self.brick_dir

    return os.path.join(self.brick_dir, 'packages')

  def SourceDir(self):
    """Returns the project's source directory."""
    return os.path.join(self.brick_dir, 'src')

  def FriendlyName(self):
    """Return the friendly name for this brick.

    This name is used as the board name for legacy commands (--board).
    """
    if self.friendly_name is None:
      raise BrickFeatureNotSupported()
    return self.friendly_name

  def BrickStack(self):
    """Returns the brick stack for this brick.

    Returns:
      A list of bricks, respecting the partial ordering of bricks as defined by
      dependencies, ordered from the lowest priority to the highest priority.
    """
    seen = set()
    def _stack(brick):
      seen.add(brick.brick_dir)
      l = []
      for dep in brick.Dependencies():
        if dep.brick_dir not in seen:
          l.extend(_stack(dep))
      l.append(brick)
      return l

    return _stack(self)


def _FindBrickInOverlays(name, base=None):
  """Returns the parent brick of |base| that matches |name|.

  Will prefer an exact match, but if one does not exist then it would settle
  for the private repo name. This is needed for backward compatibility with
  Chrome OS repo naming convention and should be adapted accordingly.

  Args:
    name: Overlay/brick name to look for.
    base: Base brick/overlay name to scan from; if None, uses |name|.

  Returns:
    The brick associated to |name| if one exists, otherwise None.
  """
  if not name:
    return None
  if base is None:
    base = name

  private_proj = None
  try:
    for overlay in portage_util.FindOverlays('both', base):
      try:
        try:
          # portage_util.FindOverlay will return an overlay list instead of a
          # brick list.
          # Use the parent directory if it is a Brick.
          proj = Brick(os.path.dirname(overlay), allow_legacy=False)
        except BrickNotFound:
          proj = Brick(overlay)
        proj_name = proj.config.get('name')
        if proj_name == name:
          return proj
        if proj_name == name + '-private':
          private_proj = proj
      except BrickNotFound:
        pass
  except portage_util.MissingOverlayException:
    pass

  return private_proj


def FindBrickInPath(path=None):
  """Returns the root directory of the brick containing a path.

  Return the first parent directory of |path| that is the root of a brick.
  This method is used for brick auto-detection and does not consider legacy.

  Args:
    path: path to a directory. If |path| is None, |path| will be set to CWD.

  Returns:
    The path to the first parent that is a brick directory if one exist.
    Otherwise return None.
  """
  for p in osutils.IteratePathParents(path or os.getcwd()):
    try:
      return Brick(p, allow_legacy=False)
    except BrickNotFound:
      pass

  return None


def FindBrickByName(name):
  """Returns the brick associated to |name|.

  Args:
    name: A brick name.

  Returns:
    The brick associated to |name| if one exists, otherwise None.
  """
  return _FindBrickInOverlays(name)
