# -*- 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.
"""Base impl of the Chrome OS Configuration access library."""

from __future__ import print_function

from collections import namedtuple, OrderedDict

import os
import sys

# pylint: disable=wrong-import-position
this_dir = os.path.dirname(__file__)
sys.path.insert(0, this_dir)
from cros_config_schema import GetValidSchemaProperties
sys.path.pop(0)

# Represents a single symbolic link firmware file which needs to be installed:
#   source: source filename of firmware file. This is installed in a
#       directory in the root filesystem
#   dest: destination filename of firmware file in the root filesystem. This is
#       in /opt/google/touch/firmware
#   symlink: name of symbolic link to put in LIB_FIRMWARE to point to the target
#       firmware. This is where Linux finds the firmware at runtime.
SymlinkedFile = namedtuple('SymlinkedFile', ['source', 'dest', 'symlink'])

# Represents a single file which needs to be installed:
#   source: Source filename within ${FILESDIR}
#   dest: Destination filename in the root filesystem
BaseFile = namedtuple('BaseFile', ['source', 'dest'])

# Represents information needed to create firmware for a model:
#   model: Name of model (e.g 'reef'). Also used as the signature ID for signing
#   shared_model: Name of model containing the shared firmware used by this
#       model, or None if this model has its own firmware images
#   key_id: Key ID used to sign firmware for this model (e.g. 'REEF')
#   have_image: True if we need to generate a setvars.sh file for this model.
#       If this is False it indicates that the model will never be detected at
#       run-time since it is a zero-touch whitelabel model. The signature ID
#       will be obtained from the customization_id in VPD when needed. Signing
#       instructions should still be generated for this model.
#   bios_build_target: Build target to use to build the BIOS, or None if none
#   ec_build_target: Build target to use to build the EC, or None if none
#   main_image_uri: URI to use to obtain main firmware image (e.g.
#       'bcs://Caroline.2017.21.1.tbz2')
#   ec_image_uri: URI to use to obtain the EC (Embedded Controller) firmware
#       image
#   pd_image_uri: URI to use to obtain the PD (Power Delivery controller)
#       firmware image
#   sig_id: Signature ID to put in the setvars.sh file. This is normally the
#       same as the model, since that is what we use for signature ID. But for
#       zero-touch whitelabel this is 'sig-id-in-customization-id' since we do
#       not know the signature ID until we look up in VPD.
#   brand-code: Uniquely identifies a given brand (see go/chromeos-rlz)
FirmwareInfo = namedtuple('FirmwareInfo', [
    'model', 'shared_model', 'key_id', 'have_image', 'bios_build_target',
    'ec_build_target', 'main_image_uri', 'main_rw_image_uri', 'ec_image_uri',
    'pd_image_uri', 'sig_id', 'brand_code'
])

# Represents the firmware image for a model:
#   type\: one of ‘ap’, ‘ec’, ‘pd’, ‘rw’.
#   build_target: The build target for given firmware image.
#   image_uri: The BCS image URI.
FirmwareImage = namedtuple('FirmwareImage',
                           ['type', 'build_target', 'image_uri'])

# Represents the signer data for a device.
#   key_id: The key ID of the device.
#   sig_id: Teh signature ID of the device.
DeviceSignerInfo = namedtuple('DeviceSignerInfo', ['key_id', 'sig_id'])


class PathComponent(object):
  """A component in a directory/file tree

  Attributes:
    name: Name this component
    children: Dict of children:
      key: Name of child
      value: PathComponent object for child
  """

  def __init__(self, name):
    self.name = name
    self.children = dict()

  def AddPath(self, path):
    parts = path.split('/', 1)
    part = parts[0]
    rest = parts[1] if len(parts) > 1 else ''
    child = self.children.get(part)
    if not child:
      child = PathComponent(part)
      self.children[part] = child
    if rest:
      child.AddPath(rest)

  def ShowTree(self, base_path, path='', indent=0):
    """Show a tree of file paths

    This shows a component and all its children. Nodes can either be directories
    or files. Each file is shown with its size, or 'missing' if not found.

    Args:
      base_path: Base path where the actual files can be found
      path: Path of this component relative to the root (e.g. 'etc/cras/)
      indent: Indent level we are up to (0 = first)
    """
    path = os.path.join(path, self.name)
    fname = os.path.join(base_path, path)
    if os.path.isdir(fname):
      status = ''
    elif os.path.exists(fname):
      status = os.stat(fname).st_size
    else:
      status = 'missing'
    print(u'%-10s%s%s%s' % (status, '   ' * indent, str(self.name),
                            self.children and '/' or ''))
    for child in sorted(self.children.keys()):
      self.children[child].ShowTree(base_path, path, indent + 1)


class DeviceConfig(object):
  """Configuration for a unique Device/SKU/Product combination.

  Provides an abstraction layer between DTS/JSON for accessing config for a
  unique Device/SKU/Product instance.
  """

  def GetName(self):
    """Returns the name of the config.

    Returns:
      Name of he config
    """

  def GetProperties(self, path):
    """Returns a map of properties at the given config path.

    Args:
      path: Path to the config desired.

    Returns:
      A map of properties at the given config path.
    """

  def GetProperty(self, path, name):
    """Returns the name value at a given path.

    Args:
      path: Path to the config desired.
      name: Property desired.

    Returns:
      Requested value or empty string if not present.
    """

  def GetFirmwareConfig(self):
    """Returns a map hierarchy of the firmware config."""
    return {}

  def GetFirmwareUris(self):
    """Returns a list of (string) firmware URIs.

    Generates and returns a list of firmeware URIs for this device. These URIs
    can be used to pull down remote firmware packages.

    Returns:
      A list of (string) full firmware URIs, or an empty list on failure.
    """
    firmware = self.GetFirmwareConfig()
    if not firmware:
      return []

    if 'bcs-overlay' not in firmware:
      return []
    # Strip "overlay-" from bcs_overlay
    bcs_overlay = firmware['bcs-overlay'][8:]
    ebuild_name = bcs_overlay.split('-')[0]
    valid_images = [p for n, p in firmware.items()
                    if n.endswith('-image') and p.startswith('bcs://')]
    # Strip "bcs://" from bcs_from images (to get the file names only)
    file_names = [p[6:] for p in valid_images]
    uri_format = ('gs://chromeos-binaries/HOME/bcs-{bcs}/overlay-{bcs}/'
                  'chromeos-base/chromeos-firmware-{ebuild_name}/{fname}')
    uris = [uri_format.format(
        bcs=bcs_overlay,
        model=self.GetName(),
        fname=fname,
        ebuild_name=ebuild_name) for fname in file_names]
    return sorted(uris)

  def GetTouchFirmwareFiles(self):
    """Get a list of unique touch firmware files

    Returns:
      List of SymlinkedFile objects representing the touch firmware referenced
        by this model
    """

  def GetDetachableBaseFirmwareFiles(self):
    """Get a list of unique detachable base firmware files

    Returns:
      List of SymlinkedFile objects representing the detachable base firmware
        referenced by this model
    """

  def GetArcFiles(self):
    """Get a list of arc++ files for this device

    Returns:
      List of BaseFile objects representing the arc++ files needed.
    """

  def GetAudioFiles(self):
    """Get a list of audio files

    Returns:
      List of BaseFile objects representing the audio files referenced
      by this device.
    """

  def GetBluetoothFiles(self):
    """Get a list of bluetooth config files

    Returns:
      List of BaseFile objects representing the bluetooth files referenced
      by this device.
    """

  def GetCameraFiles(self):
    """Get a list of camera config files

    Returns:
      List of BaseFile objects representing the camera files referenced
      by this device.
    """

  def GetThermalFiles(self):
    """Get a list of thermal files

    Returns:
      List of BaseFile objects representing the thermal files referenced
      by this device.
    """

  def GetIntelWifiSarFiles(self):
    """Get a list of intel wifi sar files

    Returns:
      List of BaseFile objects representing the intel wifi sar files referenced
      for this device.
    """

  def GetFirmwareInfo(self):
    """Gets the FirmewareInfo instance for a given device.

    Returns:
      Returns the FirmwareInfo instance.
    """

  def GetFirmwareConfigs(self):
    """Gets unique firmware configs for all devices.

    Returns:
      Dictionary of FirmwareImage objects grouped by config name.
    """

  def GetFirmwareConfigsByDevice(self):
    """Gets firmware config name for all devices.

    Returns:
      Dictionary of firmware config names grouped by device.
    """

  def GetDeviceSignerInfo(self):
    """Gets firmware signer info for all devices.

    Returns:
      Dictionary of DeviceSignerInfo grouped by device.
    """

  def GetWallpaperFiles(self):
    """Get a set of wallpaper files used for this model"""

  def GetAutobrightnessFiles(self):
    """Get a list of autobrightness files

    Returns:
      List of BaseFile objects representing the autobrightness files referenced
      by this device.
    """


class CrosConfigBaseImpl(object):
  """The ChromeOS Configuration API for the host."""

  def GetConfig(self, name):
    """Gets a (DeviceConfig) instance by name.

    Returns:
      (DeviceConfig) instance if found, else None
    """
    for device in self.GetDeviceConfigs():
      if device.GetName() == name:
        return device
    return None

  def GetDeviceConfigs(self):
    """Returns a list of (DeviceConfig) instances.

    Returns:
      A list of (DeviceConfig) instances.
    """

  def GetFullConfig(self):
    """Returns a full dict of every config returned from every API.

    Returns:
      Dictionary that maps method call onto return config.
    """
    result = {}
    result['ListModels'] = self.GetModelList()
    result['GetFirmwareUris'] = self.GetFirmwareUris()
    result['GetTouchFirmwareFiles'] = self.GetTouchFirmwareFiles()
    result['GetDetachableBaseFirmwareFiles'] = (
        self.GetDetachableBaseFirmwareFiles())
    result['GetArcFiles'] = self.GetArcFiles()
    result['GetAudioFiles'] = self.GetAudioFiles()
    bluetooth_files = self.GetBluetoothFiles()
    if bluetooth_files:
      result['GetBluetoothFiles'] = bluetooth_files
    result['GetCameraFiles'] = self.GetCameraFiles()
    result['GetThermalFiles'] = self.GetThermalFiles()
    result['GetIntelWifiSarFiles'] = self.GetIntelWifiSarFiles()
    result['GetFirmwareInfo'] = self.GetFirmwareInfo()
    for target in ['coreboot', 'ec']:
      result['GetFirmwareBuildTargets_%s' % target] = (
        self.GetFirmwareBuildTargets(target))
    result['GetFirmwareBuildCombinations'] = (
      self.GetFirmwareBuildCombinations(['coreboot', 'ec']))
    result['GetWallpaperFiles'] = self.GetWallpaperFiles()
    result['GetAutobrightnessFiles'] = self.GetAutobrightnessFiles()

    schema_properties = GetValidSchemaProperties()
    for device in self.GetDeviceConfigs():
      value_map = {}
      for path in schema_properties:
        for schema_property in schema_properties[path]:
          prop_value = device.GetProperty(path, schema_property)
          # Only dump populated values; this makes it so the config dumps
          # don't need to be updated when new schema attributes are added.
          if prop_value:
            value_map['%s::%s' % (path, schema_property)] = prop_value
      result['GetProperty_%s' % device.GetName()] = value_map
    return result


  def GetFirmwareUris(self):
    """Returns a list of (string) firmware URIs.

    Generates and returns a list of firmeware URIs for all device. These URIs
    can be used to pull down remote firmware packages.

    Returns:
      A list of (string) full firmware URIs, or an empty list on failure.
    """
    uris = set()
    for device in self.GetDeviceConfigs():
      uris.update(set(device.GetFirmwareUris()))
    return sorted(list(uris))

  def _GetFiles(self, func_name):
    """Get a list of unique files for all devices.

    Args:
      func_name: name of method to invoke on a DeviceConfig to retrieve files.

    Returns:
      list of files sorted by source.
    """
    file_set = set()
    for device in self.GetDeviceConfigs():
      for files in getattr(device, func_name)():
        file_set.add(files)

    return sorted(file_set, key=lambda files: files.source)

  def GetTouchFirmwareFiles(self):
    """Get a list of unique touch firmware files for all devices

    These files may come from ${FILESDIR} or from a tar file in BCS.

    Returns:
      List of SymlinkedFile objects representing all the touch firmware
      referenced by all devices
    """
    return self._GetFiles('GetTouchFirmwareFiles')

  def GetDetachableBaseFirmwareFiles(self):
    """Get a list of unique detachable base firmware files for all devices

    These files may come from ${FILESDIR} or from a tar file in BCS.

    Returns:
      List of SymlinkedFile objects representing all the detachable base
      firmware referenced by all devices
    """
    return self._GetFiles('GetDetachableBaseFirmwareFiles')

  def GetBcsUri(self, overlay, path):
    """Form a valid BCS URI for downloading files.

    Args:
      overlay: Name of overlay (e.g. 'reef-private')
      path: Path to file in overlay (e.g. 'chromeos-base/'
        'chromeos-touch-firmware-reef/chromeos-touch-firmware-reef-1.0-r9.tbz2')

    Returns:
      Valid BCS URI to download from
    """
    if not overlay.startswith('overlay'):
      return None
    # Strip "overlay-" from bcs_overlay.
    bcs_overlay = overlay[8:]
    return (
        'gs://chromeos-binaries/HOME/bcs-%(bcs)s/overlay-%(bcs)s/%(path)s' % {
            'bcs': bcs_overlay,
            'path': path
        })

  def GetArcFiles(self):
    """Get a list of unique Arc++ files for all devices

    Returns:
      List of BaseFile objects representing all the arc++ files referenced
      by all devices
    """
    return self._GetFiles('GetArcFiles')

  def GetAudioFiles(self):
    """Get a list of unique audio files for all models

    Returns:
      List of BaseFile objects representing all the audio files referenced
      by all models
    """
    return self._GetFiles('GetAudioFiles')

  def GetBluetoothFiles(self):
    """Get a list of unique bluetooth files for all devices

    Returns:
      List of BaseFile objects representing all the bluetooth files referenced
      by all devices
    """
    return self._GetFiles('GetBluetoothFiles')

  def GetCameraFiles(self):
    """Get a list of unique camera files for all devices

    Returns:
      List of BaseFile objects representing all the camera files referenced
      by all devices
    """
    return self._GetFiles('GetCameraFiles')

  def _GetFirmwareGroupingName(self, config):
    """Gets the name of group of firmware build targets

    Historically this maps to the name of the coreboot build target.

    Args:
      config: config object that contains /firmware node

    Returns:
      A string of the firmware group name
    """
    # Use coreboot as key if it exist to support historical use case of
    # grouping firmware build targets by coreboot name
    key = config.GetProperty('/firmware/build-targets', 'coreboot')
    if key:
      return key
    # Otherwise use the image-name. There are very few cases of having an
    # image-name without also having a coreboot image
    return config.GetProperty('/firmware', 'image-name')

  def GetFirmwareBuildTargets(self, target_type):
    """Returns a list of all firmware build-targets of the given target type.

    Args:
      target_type: A string type for the build-targets to return

    Returns:
      A list of all build-targets of the given type, for all models.
    """
    firmware_filter = os.getenv('FW_NAME')
    build_targets = []
    for device in self.GetDeviceConfigs():
      device_targets = device.GetProperties('/firmware/build-targets')
      # Skip nodes with no build targets
      if not device_targets:
        continue

      key = self._GetFirmwareGroupingName(device)

      if firmware_filter and key != firmware_filter:
        continue
      if target_type in device_targets:
        build_targets.append(device_targets[target_type])
      if target_type == 'ec':
        for ec_extra in ('base', ):
          if ec_extra in device_targets:
            build_targets.append(device_targets[ec_extra])
        if 'ec_extras' in device_targets:
          for extra_target in device_targets['ec_extras']:
            build_targets.append(extra_target)
    return sorted(set(build_targets))

  def GetFirmwareBuildCombinations(self, components):
    """Get named firmware build combinations for all devices.

    Args:
      components: List of firmware components to get target combinations for.

    Returns:
      OrderedDict containing firmware combinations
        key: combination name
        value: list of firmware targets for specified types

    Raises:
      ValueError if a collision is encountered for named combinations.
    """
    firmware_filter = os.getenv('FW_NAME')

    combos = OrderedDict()
    for device in self.GetDeviceConfigs():
      device_targets = device.GetProperties('/firmware/build-targets')
      # Skip device_targetss with no build targets
      if not device_targets:
        continue
      targets = [device_targets.get(c) for c in components]

      key = self._GetFirmwareGroupingName(device)

      if firmware_filter and key != firmware_filter:
        continue

      if key in combos and targets != combos[key]:
        raise ValueError('Colliding firmware combinations found for key %s: '
                         '%s, %s' % (key, targets, combos[key]))
      combos[key] = targets
    return OrderedDict(sorted(combos.items()))

  def GetThermalFiles(self):
    """Get a list of unique thermal files for all models

    Returns:
      List of BaseFile objects representing all the audio files referenced
      by all devices
    """
    return self._GetFiles('GetThermalFiles')

  def GetIntelWifiSarFiles(self):
    """Get a list of unique intel wifi sar files for all models

    Returns:
      List of BaseFile objects representing all the intel wifi sar files
      referenced by all devices
    """
    return self._GetFiles('GetIntelWifiSarFiles')

  def ShowTree(self, base_path, tree):
    print(u'%-10s%s' % ('Size', 'Path'))
    tree.ShowTree(base_path)

  def GetFileTree(self):
    """Get a tree of all files installed by the config

    This looks at all available config that installs files in the root and
    returns them as a tree structure. This can be passed to ShowTree(), which
    is the only feature currently implemented which uses this tree.

    Returns:
      PathComponent object containing the root component
    """
    paths = set()
    for item in self.GetAudioFiles():
      paths.add(item.dest)
    for item in self.GetTouchFirmwareFiles():
      paths.add(item.dest)
      paths.add(item.symlink)
    root = PathComponent('')
    for path in paths:
      root.AddPath(path[1:])

    return root

  def GetModelList(self):
    """Return a list of models

    Returns:
      List of model names, each a string
    """
    return sorted(set([device.GetName() for device in self.GetDeviceConfigs()]))

  def GetFirmwareInfo(self):
    firmware_info = OrderedDict()
    for name in self.GetModelList():
      for device in self.GetDeviceConfigs():
        if device.GetName() == name:
          firmware_info.update(device.GetFirmwareInfo())
    return firmware_info

  def GetWallpaperFiles(self):
    """Get a list of wallpaper files used for all models"""
    wallpapers = set()
    for device in self.GetDeviceConfigs():
      wallpapers |= device.GetWallpaperFiles()
    return sorted(wallpapers)

  def GetAutobrightnessFiles(self):
    """Get a list of unique autobrightness files for all models

    Returns:
      List of BaseFile objects representing all the autobrightness files
      referenced by all devices
    """
    return self._GetFiles('GetAutobrightnessFiles')
