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

"""The Binhost API interacts with Portage binhosts and Packages files."""

from __future__ import print_function

import functools
import os

from chromite.lib import binpkg
from chromite.lib import constants
from chromite.lib import cros_build_lib
from chromite.lib import osutils
from chromite.lib import parallel
from chromite.lib import portage_util
from chromite.utils import key_value_store


# The name of the ACL argument file.
_GOOGLESTORAGE_GSUTIL_FILE = 'googlestorage_acl.txt'

# The name of the package file (relative to sysroot) where the list of packages
# for dev-install is stored.
_DEV_INSTALL_PACKAGES_FILE = 'build/dev-install/package.installable'


class Error(Exception):
  """Base error class for the module."""


class EmptyPrebuiltsRoot(Error):
  """When a prebuilts root is unexpectedly empty."""


class NoAclFileFound(Error):
  """No ACL file could be found."""


def _ValidateBinhostConf(path, key):
  """Validates the binhost conf file defines only one environment variable.

  This function is effectively a sanity check that ensures unexpected
  configuration is not clobbered by conf overwrites.

  Args:
    path: Path to the file to validate.
    key: Expected binhost key.

  Raises:
    ValueError: If file defines != 1 environment variable.
  """
  if not os.path.exists(path):
    # If the conf file does not exist, e.g. with new targets, then whatever.
    return

  kvs = key_value_store.LoadFile(path)

  if not kvs:
    raise ValueError(
        'Found empty .conf file %s when a non-empty one was expected.' % path)
  elif len(kvs) > 1:
    raise ValueError(
        'Conf file %s must define exactly 1 variable. '
        'Instead found: %r' % (path, kvs))
  elif key not in kvs:
    raise KeyError('Did not find key %s in %s' % (key, path))


def _ValidatePrebuiltsFiles(prebuilts_root, prebuilts_paths):
  """Validate all prebuilt files exist.

  Args:
    prebuilts_root: Absolute path to root directory containing prebuilts.
    prebuilts_paths: List of file paths relative to root, to be verified.

  Raises:
    LookupError: If any prebuilt archive does not exist.
  """
  for prebuilt_path in prebuilts_paths:
    full_path = os.path.join(prebuilts_root, prebuilt_path)
    if not os.path.exists(full_path):
      raise LookupError('Prebuilt archive %s does not exist' % full_path)


def _ValidatePrebuiltsRoot(target, prebuilts_root):
  """Validate the given prebuilts root exists.

  If the root does not exist, it probably means the build target did not build
  successfully, so warn callers appropriately.

  Args:
    target: The build target in question.
    prebuilts_root: The expected root directory for the target's prebuilts.

  Raises:
    EmptyPrebuiltsRoot: If prebuilts root does not exist.
  """
  if not os.path.exists(prebuilts_root):
    raise EmptyPrebuiltsRoot(
        'Expected to find prebuilts for build target %s at %s. '
        'Did %s build successfully?' % (target, prebuilts_root, target))


def GetPrebuiltsRoot(chroot, sysroot, build_target):
  """Find the root directory with binary prebuilts for the given sysroot.

  Args:
    chroot (chroot_lib.Chroot): The chroot where the sysroot lives.
    sysroot (sysroot_lib.Sysroot): The sysroot.
    build_target (build_target_lib.BuildTarget): The build target.

  Returns:
    Absolute path to the root directory with the target's prebuilt archives.
  """
  root = os.path.join(chroot.path, sysroot.path.lstrip(os.sep), 'packages')
  _ValidatePrebuiltsRoot(build_target, root)
  return root


def GetPrebuiltsFiles(prebuilts_root):
  """Find paths to prebuilts at the given root directory.

  Assumes the root contains a Portage package index named Packages.

  The package index paths are used to de-duplicate prebuilts uploaded. The
  immediate consequence of this is reduced storage usage. The non-obvious
  consequence is the shared packages generally end up with public permissions,
  while the board-specific packages end up with private permissions. This is
  what is meant to happen, but a further consequence of that is that when
  something happens that causes the toolchains to be uploaded as a private
  board's package, the board will not be able to build properly because
  it won't be able to fetch the toolchain packages, because they're expected
  to be public.

  Args:
    prebuilts_root: Absolute path to root directory containing a package index.

  Returns:
    List of paths to all prebuilt archives, relative to the root.
  """
  package_index = binpkg.GrabLocalPackageIndex(prebuilts_root)
  prebuilt_paths = []
  for package in package_index.packages:
    prebuilt_paths.append(package['CPV'] + '.tbz2')

    include_debug_symbols = package.get('DEBUG_SYMBOLS')
    if cros_build_lib.BooleanShellValue(include_debug_symbols, default=False):
      prebuilt_paths.append(package['CPV'] + '.debug.tbz2')

  _ValidatePrebuiltsFiles(prebuilts_root, prebuilt_paths)
  return prebuilt_paths


def UpdatePackageIndex(prebuilts_root, upload_uri, upload_path, sudo=False):
  """Update package index with information about where it will be uploaded.

  This causes the existing Packages file to be overwritten.

  Args:
    prebuilts_root: Absolute path to root directory containing binary prebuilts.
    upload_uri: The URI (typically GS bucket) where prebuilts will be uploaded.
    upload_path: The path at the URI for the prebuilts.
    sudo (bool): Whether to write the file as the root user.

  Returns:
    Path to the new Package index.
  """
  assert not upload_path.startswith('/')
  package_index = binpkg.GrabLocalPackageIndex(prebuilts_root)
  package_index.SetUploadLocation(upload_uri, upload_path)
  package_index.header['TTL'] = 60 * 60 * 24 * 365
  package_index_path = os.path.join(prebuilts_root, 'Packages')
  package_index.WriteFile(package_index_path, sudo=sudo)
  return package_index_path


def SetBinhost(target, key, uri, private=True):
  """Set binhost configuration for the given build target.

  A binhost is effectively a key (Portage env variable) pointing to a URL
  that contains binaries. The configuration is set in .conf files at static
  directories on a build target by build target (and host by host) basis.

  This function updates the .conf file by completely rewriting it.

  Args:
    target: The build target to set configuration for.
    key: The binhost key to set, e.g. POSTSUBMIT_BINHOST.
    uri: The new value for the binhost key, e.g. gs://chromeos-prebuilt/foo/bar.
    private: Whether or not the build target is private.

  Returns:
    Path to the updated .conf file.
  """
  conf_root = os.path.join(
      constants.SOURCE_ROOT,
      constants.PRIVATE_BINHOST_CONF_DIR if private else
      constants.PUBLIC_BINHOST_CONF_DIR, 'target')
  conf_file = '%s-%s.conf' % (target, key)
  conf_path = os.path.join(conf_root, conf_file)
  _ValidateBinhostConf(conf_path, key)
  osutils.WriteFile(conf_path, '%s="%s"' % (key, uri))
  return conf_path


def RegenBuildCache(chroot, overlay_type):
  """Regenerate the Build Cache for the given target.

  Args:
    chroot (chroot_lib): The chroot where the regen command will be run.
    overlay_type: one of "private", "public", or "both".

  Returns:
    list[str]: The overlays with updated caches.
  """
  overlays = portage_util.FindOverlays(overlay_type)

  task = functools.partial(
      portage_util.RegenCache, commit_changes=False, chroot=chroot)
  task_inputs = [[o] for o in overlays if os.path.isdir(o)]
  results = parallel.RunTasksInProcessPool(task, task_inputs)

  # Filter out all of the unchanged-overlay results.
  return [overlay_dir for overlay_dir in results if overlay_dir]


def GetPrebuiltAclArgs(build_target):
  """Read and parse the GS ACL file from the private overlays.

  Args:
    build_target (build_target_lib.BuildTarget): The build target.

  Returns:
    list[list[str]]: A list containing all of the [arg, value] pairs. E.g.
      [['-g', 'group_id:READ'], ['-u', 'user:FULL_CONTROL']]
  """
  acl_file = portage_util.FindOverlayFile(_GOOGLESTORAGE_GSUTIL_FILE,
                                          board=build_target.name)

  if not acl_file:
    raise NoAclFileFound('No ACL file found for %s.' % build_target.name)

  lines = osutils.ReadFile(acl_file).splitlines()
  # Remove comments.
  lines = [line.split('#', 1)[0].strip() for line in lines]
  # Remove empty lines.
  lines = [line.strip() for line in lines if line.strip()]

  return [line.split() for line in lines]


def GetBinhosts(build_target):
  """Get the binhosts for the build target.

  Args:
    build_target (build_target_lib.BuildTarget): The build target.

  Returns:
    list[str]: The build target's binhosts.
  """
  binhosts = portage_util.PortageqEnvvar('PORTAGE_BINHOST',
                                         board=build_target.name,
                                         allow_undefined=True)
  return binhosts.split() if binhosts else []


def ReadDevInstallPackageFile(filename):
  """Parse the dev-install package file.

  Args:
    filename (str): The full path to the dev-install package list.

  Returns:
    list[str]: The packages in the package list file.
  """
  with open(filename) as f:
    return [line.strip() for line in f]


def ReadDevInstallFilesToCreatePackageIndex(chroot, sysroot, package_index_path,
                                            upload_uri, upload_path):
  """Create dev-install Package index specified by package_index_path

  The current Packages file is read and a new Packages file is created based
  on the subset of packages in the _DEV_INSTALL_PACKAGES_FILE.

  Args:
    chroot (chroot_lib.Chroot): The chroot where the sysroot lives.
    sysroot (sysroot_lib.Sysroot): The sysroot.
    package_index_path (str): Path to the Packages file to be created.
    upload_uri: The URI (typically GS bucket) where prebuilts will be uploaded.
    upload_path: The path at the URI for the prebuilts.

  Returns:
    list[str]: The list of packages contained in package_index_path,
      where each package string is a category/file.
  """
  # Read the dev-install binhost package file
  devinstall_binhost_filename = chroot.full_path(sysroot.path,
                                                 _DEV_INSTALL_PACKAGES_FILE)
  devinstall_package_list = ReadDevInstallPackageFile(
      devinstall_binhost_filename)

  # Read the Packages file, remove packages not in package_list
  package_path = chroot.full_path(sysroot.path, 'packages')
  CreateFilteredPackageIndex(package_path, devinstall_package_list,
                             package_index_path,
                             upload_uri, upload_path)

  # We have the list of packages, create full path and verify each one.
  upload_targets_list = GetPrebuiltsForPackages(
      package_path, devinstall_package_list)

  return upload_targets_list


def CreateFilteredPackageIndex(package_path, devinstall_package_list,
                               package_index_path,
                               upload_uri, upload_path, sudo=False):
  """Create Package file for dev-install process.

  The created package file (package_index_path) contains only the
  packages from the system packages file (in package_path) that are in the
  devinstall_package_list. The new package file will use the provided values
  for upload_uri and upload_path.

  Args:
    package_path (str): Absolute path to the standard Packages file.
    devinstall_package_list (list[str]): Packages from packages.installable
    package_index_path (str): Absolute path for new Packages file.
    upload_uri (str): The URI where prebuilts will be uploaded.
    upload_path (str): The path at the URI for the prebuilts.
    sudo (bool): Whether to write the file as the root user.
  """


  def ShouldFilterPackage(package):
    """Local func to filter packages not in the devinstall_package_list

    Args:
      package (dict): Dictionary with key 'CPV' and package name as value

    Returns:
      True (filter) if not in the devinstall_package_list, else False (don't
        filter) if in the devinstall_package_list
    """
    value = package['CPV']
    if value in devinstall_package_list:
      return False
    else:
      return True

  package_index = binpkg.GrabLocalPackageIndex(package_path)
  package_index.RemoveFilteredPackages(ShouldFilterPackage)
  package_index.SetUploadLocation(upload_uri, upload_path)
  package_index.header['TTL'] = 60 * 60 * 24 * 365
  package_index.WriteFile(package_index_path, sudo=sudo)


def GetPrebuiltsForPackages(package_root, package_list):
  """Create list of file paths for the package list and validate they exist.

  Args:
    package_root (str): Path to 'packages' directory.
    package_list (list[str]): List of packages.

  Returns:
    List of validated targets.
  """
  upload_targets_list = []
  for pkg in package_list:
    zip_target = pkg + '.tbz2'
    upload_targets_list.append(zip_target)
    full_pkg_path = os.path.join(package_root, pkg) + '.tbz2'
    if not os.path.exists(full_pkg_path):
      raise LookupError('DevInstall archive %s does not exist' % full_pkg_path)
  return upload_targets_list
