# -*- coding: utf-8 -*-
# Copyright 2020 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.

"""Utilities for setting up Portage objects for testing."""

from __future__ import print_function
from __future__ import division

import itertools
import os
import pathlib  # pylint: disable=import-error
import shlex
from typing import Dict, Iterable, Tuple, Union

from chromite.lib import constants
from chromite.lib import cros_build_lib
from chromite.lib import osutils
from chromite.lib.parser import package_info

__all__ = ['Overlay', 'Package', 'Profile', 'Sysroot']

_EXCLUDED_OVERLAYS = ('chromiumos', 'portage-stable')


def _dict_to_conf(dictionary):
  """Helper to format a dictionary into a layout.conf file."""
  output = []
  for key in sorted(dictionary.keys()):
    output.append('%s = %s' % (key, dictionary[key]))

  output.append('\n')
  return '\n'.join(output)


def _dict_to_ebuild(dictionary):
  """Helper to format a dictionary into an ebuild file."""
  output = []
  for key in dictionary.keys():
    output.append(f'{key}={shlex.quote(dictionary[key])}')

  output.append('\n')
  return '\n'.join(output)


class Overlay(object):
  """Portage overlay object, responsible for all writes to its directory."""

  HIERARCHY_NAMES = ('stable', 'project', 'chipset', 'baseboard', 'board',
                     'board-private')

  def __init__(self, root_path, name, masters=None):
    self.path = pathlib.Path(root_path)
    self.name = str(name)
    self.masters = tuple(masters) if masters else None
    self.packages = []
    self.profiles = dict()
    self.categories = set()

    self._write_layout_conf()

  def __contains__(self, item: Union[package_info.CPV,
                                     package_info.PackageInfo]):
    if not isinstance(item, (package_info.CPV, package_info.PackageInfo)):
      raise TypeError(f'Expected a CPV but received a {type(item)}')

    if isinstance(item, package_info.CPV):
      ebuild_path = (
          self.path / item.category / item.package / f'{item.pv}.ebuild')
    else:
      ebuild_path = self.path / item.relative_path

    return ebuild_path.is_file()

  def _write_layout_conf(self):
    """Write out the layout.conf as part of this Overlay's initialization."""
    layout_conf_path = self.path / 'metadata' / 'layout.conf'
    master_names = ' '.join(m.name for m in self.masters or [])
    conf = {
        'masters': 'portage-stable chromiumos eclass-overlay' + master_names,
        'profile-formats': 'portage-2 profile-default-eapi',
        'profile_eapi_when_unspecified': '5-progress',
        'repo-name': str(self.name),
        'thin-manifests': 'true',
        'use-manifests': 'strict',
    }

    osutils.WriteFile(layout_conf_path, _dict_to_conf(conf), makedirs=True)

  def add_package(self, pkg):
    """Add a package to this overlay.

    Adds the package to the Overlay object's internal storage and writes the
    package metadata to the Overlay's directory.
    """
    self.packages.append(pkg)
    self._write_ebuild(pkg)
    if pkg.category not in self.categories:
      self.categories.add(pkg.category)
      osutils.WriteFile(
          self.path / 'profiles' / 'categories',
          pkg.category + '\n',
          mode='a',
          makedirs=True)

  def _write_ebuild(self, pkg: 'Package'):
    """Write a Package object out to an ebuild file in this Overlay."""
    ebuild_path = self.path / pkg.category / pkg.package / (
        pkg.package + '-' + pkg.version + '.ebuild')

    # EAPI must be the first thing defined in a ebuild, so write this config
    # before anything else.
    base_conf = {
        'EAPI': pkg.eapi,
        'KEYWORDS': pkg.keywords,
        'SLOT': pkg.slot,
    }

    osutils.WriteFile(ebuild_path, _dict_to_ebuild(base_conf), makedirs=True)

    # Write additional miscellaneous variables declared in the Package object.
    for k, v in pkg.variables.items():
      osutils.WriteFile(ebuild_path, f'{k}="{v}"\n', mode='a')

    # Write an eclass inheritance line, if needed.
    if pkg.format_eclass_line():
      osutils.WriteFile(ebuild_path, pkg.format_eclass_line(), mode='a')

    extra_conf = {
        'DEPEND': pkg.depend,
        'RDEPEND': pkg.rdepend,
    }

    osutils.WriteFile(ebuild_path, _dict_to_ebuild(extra_conf), mode='a')

  def create_profile(self, path=None, profile_parents=None, make_defaults=None):
    """Create a profile in this overlay.

    Creates a profile with the given settings and writes the profile with those
    settings to the Overlay's directory.
    """
    path = pathlib.Path(path) if path else pathlib.Path('base')
    if path in self.profiles:
      raise KeyError('A profile with that path already exists!')

    prof = Profile(
        self, path, parents=profile_parents, make_defaults=make_defaults)

    self._write_profile(prof)
    self.profiles[path] = prof

    return prof

  def _write_profile(self, profile):
    """Write a Profile object out to this Overlay's directory."""
    osutils.WriteFile(
        self.path / 'profiles' / profile.path / 'make.defaults',
        _dict_to_ebuild(profile.make_defaults),
        makedirs=True)
    if profile.parents:
      formatted_parents = []
      for parent in profile.parents:
        formatted_parents.append(str(parent.overlay) + ':' + str(parent.path))
      osutils.WriteFile(self.path / 'profiles' / profile.path / 'parents',
                        '\n'.join(formatted_parents) + '\n')


class Sysroot(object):
  """Sysroot object representing a functional Portage directory for testing."""

  # These PORTDIR_OVERLAY entries are necessary for any Portage operations to
  # function as the chroot's profile is parsed first, even if that profile is
  # not used by the sysroot at all.
  # This tuple should effectively be:
  # /mnt/host/source/src/third_party/portage-stable
  # /mnt/host/source/src/third_party/chromiumos-overlay
  # /mnt/host/source/src/third_party/eclass-overlay
  _BOOTSTRAP_PORTDIR_OVERLAYS = (
      os.path.join(constants.CHROOT_SOURCE_ROOT,
                   constants.PORTAGE_STABLE_OVERLAY_DIR),
      os.path.join(constants.CHROOT_SOURCE_ROOT,
                   constants.CHROMIUMOS_OVERLAY_DIR),
      os.path.join(constants.CHROOT_SOURCE_ROOT, constants.ECLASS_OVERLAY_DIR),
  )

  def __init__(self, path, profile, overlays):
    self.path = path

    osutils.SafeMakedirs(path / 'etc' / 'portage' / 'profile')
    osutils.SafeMakedirs(path / 'etc' / 'portage' / 'hooks')

    osutils.SafeSymlink(profile.full_path,
                        path / 'etc' / 'portage' / 'make.profile')

    sysroot_conf = {
        'ACCEPT_KEYWORDS':
            'amd64',
        'ROOT':
            str(self.path),
        'SYSROOT':
            str(self.path),
        'ARCH':
            'amd64',
        'PORTAGE_CONFIGROOT':
            str(self.path),
        'PORTDIR':
            str(overlays[0].path),
        'PORTDIR_OVERLAY':
            '\n'.join(
                itertools.chain((str(o.path) for o in overlays),
                                Sysroot._BOOTSTRAP_PORTDIR_OVERLAYS)),
        'PORTAGE_BINHOST':
            '',
        'USE':
            '',
        'PKGDIR':
            str(self.path / 'packages'),
        'PORTAGE_TMPDIR':
            str(self.path / 'tmp'),
        'DISTDIR':
            str(self.path / 'var' / 'lib' / 'portage' / 'distfiles'),
    }

    osutils.WriteFile(self.path / 'etc' / 'portage' / 'make.conf',
                      _dict_to_ebuild(sysroot_conf))

    osutils.WriteFile(self.path / 'etc' / 'portage' / 'package.mask',
                      ''.join(f'*/*::{o}\n' for o in _EXCLUDED_OVERLAYS))

  @property
  def _env(self):
    """Return a dict of the environment variables for this sysroot."""
    return {
        'PORTAGE_CONFIGROOT': str(self.path),
        'ROOT': str(self.path),
        'SYSROOT': str(self.path),
        'BROOT': str(self.path),
    }

  def run(self, cmd, **kwargs):
    """Run a command against this sysroot.

    This method sets up the equivalent calling environment to the `emerge`
    wrappers we generate but targeted at this specific sysroot, which has
    an arbitrary path in the test environment. This means that Portage commands
    such as `equery list '*'` will correctly run against this sysroot.
    """
    extra_env = self._env
    extra_env.update(kwargs.pop('extra_env', {}))
    kwargs.setdefault('encoding', 'utf-8')

    return cros_build_lib.run(cmd, extra_env=extra_env, **kwargs)


class Profile(object):
  """Portage profile, lives in an overlay."""

  def __init__(self, overlay, path, parents=None, make_defaults=None):
    self.overlay = overlay.name
    self.path = path
    self.full_path = overlay.path / 'profiles' / path
    self.parents = tuple(parents) if parents else None
    self.make_defaults = make_defaults if make_defaults else {'USE': ''}


class Package(object):
  """Portage package, lives in an overlay."""

  inherit: Tuple[str]
  variables: Dict[str, str]

  def __init__(self,
               category,
               package,
               version='1',
               eapi='7',
               keywords='*',
               slot='0',
               depend='',
               rdepend='',
               inherit: Union[Iterable[str], str] = tuple(),
               **kwargs):
    self.category = category
    self.package = package
    self.version = version
    self.eapi = eapi
    self.keywords = keywords
    self.slot = slot
    self.depend = depend
    self.rdepend = rdepend
    self.inherit = (inherit,) if isinstance(inherit, str) else tuple(inherit)
    self.variables = kwargs

  @classmethod
  def from_cpv(cls, pkg_str: str):
    """Creates a Package from a CPV string."""
    cpv = package_info.parse(pkg_str)
    return cls(category=cpv.category, package=cpv.package, version=cpv.vr)

  @property
  def cpv(self) -> package_info.CPV:
    """Returns a CPV object constructed from this package's metadata."""
    return package_info.SplitCPV(self.category + '/' + self.package + '-' +
                                 self.version)

  def format_eclass_line(self) -> str:
    """Returns a string containing this package's eclass inheritance line."""
    if self.inherit and isinstance(self.inherit, str):
      return f'inherit {self.inherit}\n'
    elif self.inherit:
      return f'inherit {" ".join(self.inherit)}\n'
    else:
      return ''
