# -*- 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'])

  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 GetIntelWifiSarFiles(self):
    return self._GetSystemFileV2('/wifi/sar-file')

  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
    }
