# -*- coding: utf-8 -*-
# Copyright 2017 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.
"""Crome OS Configuration access library.

Provides build-time access to the master configuration on the host. It is used
for reading from the master configuration. Consider using cros_config_host.py
for CLI access to this library.
"""

from __future__ import print_function

from collections import OrderedDict
import copy
import json
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 TransformConfig
from cros_config_schema import GetValidSchemaProperties
from libcros_config_host_base import BaseFile, CrosConfigBaseImpl, DeviceConfig
from libcros_config_host_base import FirmwareInfo, SymlinkedFile
from libcros_config_host_base import FirmwareImage, DeviceSignerInfo
sys.path.pop(0)


UNIBOARD_JSON_INSTALL_PATH = 'usr/share/chromeos-config/config.json'


class DeviceConfigJson(DeviceConfig):
  """JSON specific impl of DeviceConfig

  Attributes:
    _config: Root dictionary element for a given config.
  """

  def __init__(self, config):
    self._schema_properties = GetValidSchemaProperties()
    self._config = config
    self.firmware_info = OrderedDict()

  def GetName(self):
    return str(self._config['name'])

  def GetProperties(self, path):
    result = self._config
    if path != '/':
      for path_token in path[1:].split('/'):  # Burn the first '/' char
        if path_token in result:
          result = result[path_token]
        else:
          return {}
    return result

  def GetProperty(self, path, name):
    schema_props = self._schema_properties.get(path, None)
    if not schema_props or not name in schema_props:
      raise Exception('Property not present in schema: %s:%s' % (path, name))
    props = self.GetProperties(path)
    if props and name in props:
      return str(props[name])
    return ''

  def GetValue(self, source, name):
    return source.get(name, None)

  def _GetFiles(self, path):
    result = []
    file_region = self.GetProperties(path)
    if file_region and 'files' in file_region:
      for item in file_region['files']:
        if 'build-path' in item:
          result.append(BaseFile(item['build-path'], item['system-path']))
        else:
          result.append(BaseFile(item['source'], item['destination']))
    return result

  def _GetSymlinkedFiles(self, path):
    result = []
    items = self.GetProperties(path)
    if items and 'files' in items:
      for item in items['files']:
        result.append(
            SymlinkedFile(item['source'], item['destination'], item['symlink']))

    return result

  def _GetSystemFileV2(self, path):
    return self._GetSystemFilesV2([path])

  def _GetSystemFilesV2(self, paths):
    result = []
    for path in paths:
      config = self.GetProperties(path)
      if config:
        result.append(BaseFile(config['build-path'], config['system-path']))
    return result

  def GetFirmwareConfig(self):
    firmware = self.GetProperties('/firmware')
    if not firmware or self.GetValue(firmware, 'no-firmware'):
      return {}
    return firmware

  def GetFirmwareInfo(self):
    return self.firmware_info

  def GetTouchFirmwareFiles(self):
    return self._GetSymlinkedFiles('/touch')

  def GetDetachableBaseFirmwareFiles(self):
    return self._GetSymlinkedFiles('/detachable-base')

  def GetArcFiles(self):
    return self._GetSystemFilesV2([
        '/arc/hardware-features',
        '/arc/media-profiles',
        '/arc/camera-characteristics'])

  def GetAudioFiles(self):
    return self._GetFiles('/audio/main')

  def GetBluetoothFiles(self):
    return self._GetSystemFileV2('/bluetooth/config')

  def GetCameraFiles(self):
    return self._GetSystemFileV2('/camera/config-file')

  def GetThermalFiles(self):
    return self._GetFiles('/thermal')

  def GetWallpaperFiles(self):
    result = set()
    wallpaper = self.GetValue(self._config, 'wallpaper')
    if wallpaper:
      result.add(wallpaper)
    return result

  def GetAutobrightnessFiles(self):
    return self._GetSystemFileV2('/power/autobrightness/config-file')


class CrosConfigJson(CrosConfigBaseImpl):
  """JSON specific impl of CrosConfig

  Attributes:
    _json: Root json for the entire config.
    _configs: List of DeviceConfigJson instances
  """

  def __init__(self, infile, model_filter_regex=None):
    """Constructor for JSON specific implementation of CrosConfig

    Args:
      infile: File-like object with JSON configuration
      model_filter_regex: Only returns configs that match the filter.
    """
    self._json = json.loads(
        TransformConfig(infile.read(), model_filter_regex=model_filter_regex))
    self._configs = []
    for config in self._json['chromeos']['configs']:
      self._configs.append(DeviceConfigJson(config))

    sorted(self._configs, key=lambda x: str(x.GetProperties('/identity')))

    # TODO(shapiroc): This is mess and needs considerable rework on the fw
    # side to cleanup, but for now, we're sticking with it in order to
    # finish migration to YAML.
    fw_by_model = {}
    processed = set()
    for config in self._configs:
      fw = config.GetFirmwareConfig()
      # For partial configs (public vs private), we need to support the name
      # for cases where identity isn't specified.
      identity = config.GetName() + str(config.GetProperties('/identity'))
      brand_code = config.GetProperty('/', 'brand-code')
      if fw and identity not in processed:
        fw_str = str(fw)
        shared_model = None
        if fw_str not in fw_by_model:
          # Use the explict name of the firmware, else use the device name
          # This supports equivalence testing with DT since it allowed
          # naming firmware images.
          fw_by_model[fw_str] = fw.get('name', config.GetName())

        shared_model = fw_by_model[fw_str]

        build_config = config.GetProperties('/firmware/build-targets')
        if build_config:
          bios_build_target = config.GetValue(build_config, 'coreboot')
          ec_build_target = config.GetValue(build_config, 'ec')
        else:
          bios_build_target, ec_build_target = None, None

        main_image_uri = config.GetValue(fw, 'main-ro-image') or ''
        main_rw_image_uri = config.GetValue(fw, 'main-rw-image') or ''
        ec_image_uri = config.GetValue(fw, 'ec-ro-image') or ''
        pd_image_uri = config.GetValue(fw, 'pd-ro-image') or ''

        fw_signer_config = config.GetProperties('/firmware-signing')
        key_id = config.GetValue(fw_signer_config, 'key-id')
        sig_in_customization_id = config.GetValue(fw_signer_config,
                                                  'sig-id-in-customization-id')

        have_image = True
        name = config.GetName()

        if sig_in_customization_id:
          sig_id = 'sig-id-in-customization-id'
          brand_code = ''
        else:
          sig_id = config.GetValue(fw_signer_config, 'signature-id')
          processed.add(identity)

        info = FirmwareInfo(name, 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)
        config.firmware_info[name] = info

        if sig_in_customization_id:
          for wl_config in self._configs:
            if wl_config.GetName() == name:
              wl_brand_code = wl_config.GetProperty('/', 'brand-code')
              wl_identity_str = str(wl_config.GetProperties('/identity'))
              wl_identity = wl_config.GetName() + wl_identity_str
              processed.add(wl_identity)
              fw_signer_config = wl_config.GetProperties('/firmware-signing')
              wl_key_id = wl_config.GetValue(fw_signer_config, 'key-id')
              wl_sig_id = wl_config.GetValue(fw_signer_config, 'signature-id')
              wl_fw_info = copy.deepcopy(info)
              # Firmware info associated with model name should be kept with
              # have_image=True so following process will generate one firmware
              # entry for this model.
              if wl_sig_id == name:
                wl_config.firmware_info[wl_sig_id] = wl_fw_info._replace(
                    brand_code=wl_brand_code)
              else:
                wl_config.firmware_info[wl_sig_id] = wl_fw_info._replace(
                    model=wl_sig_id,
                    key_id=wl_key_id,
                    have_image=False,
                    sig_id=wl_sig_id,
                    brand_code=wl_brand_code)

  def GetDeviceConfigs(self):
    return self._configs

  def GetFirmwareConfigs(self):
    result = dict()
    for value in self.GetFirmwareInfo().values():
      fw_images = []
      ap_build_target = value.bios_build_target
      ec_build_target = value.ec_build_target
      if value.main_image_uri:
        fw_images.append(
            FirmwareImage(
                type='ap',
                build_target=ap_build_target,
                image_uri=value.main_image_uri))
      if value.main_rw_image_uri:
        fw_images.append(
            FirmwareImage(
                type='rw',
                build_target=ap_build_target,
                image_uri=value.main_rw_image_uri))
      if value.ec_image_uri:
        fw_images.append(
            FirmwareImage(
                type='ec',
                build_target=ec_build_target,
                image_uri=value.ec_image_uri))
      if value.pd_image_uri:
        fw_images.append(
            FirmwareImage(
                type='pd',
                build_target=ec_build_target,
                image_uri=value.pd_image_uri))

      result[value.shared_model] = fw_images

    return result

  def GetFirmwareConfigsByDevice(self):
    return {
        value.model: value.shared_model or value.model
        for value in self.GetFirmwareInfo().values()
    }

  def GetDeviceSignerInfo(self):
    return {
        value.model: DeviceSignerInfo(key_id=value.key_id, sig_id=value.sig_id)
        for value in self.GetFirmwareInfo().values()
        if value.key_id
    }
