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

"""A type used to represent a toolchain and its setting overrides."""

from __future__ import print_function

import copy
import collections
import json
import os
import sys

from chromite.lib import osutils


assert sys.version_info >= (3, 6), 'This module requires Python 3.6+'


_ToolchainTuple = collections.namedtuple('_ToolchainTuple',
                                         ('target', 'setting_overrides'))


_DEFAULT_TOOLCHAIN_KEY = 'default'


class MismatchedToolchainConfigsError(Exception):
  """We have no defined resolution for conflicting toolchain configs."""


class ToolchainList(object):
  """Represents a list of toolchains."""

  def __init__(self, overlays):
    """Construct an instance.

    Args:
      overlays: list of overlay directories to add toolchains from.
    """
    if overlays is None:
      raise ValueError('Must specify overlays.')

    self._toolchains = []
    self._auto_default_toolchain = None
    for overlay_path in overlays:
      self._AddToolchainsFromOverlayDir(overlay_path)

  def _AddToolchainsFromOverlayDir(self, overlay_dir):
    """Add toolchains to |self| from the given overlay.

    Does not include overlays that this overlay depends on.

    Args:
      overlay_dir: absolute path to an overlay directory.
    """
    config_path = os.path.join(overlay_dir, 'toolchain.conf')
    if not os.path.exists(config_path):
      # Not all overlays define toolchains.
      return

    first_target = True
    default_target = None

    config_lines = osutils.ReadFile(config_path).splitlines()
    for line in config_lines:
      # Split by hash sign so that comments are ignored.
      # Then split the line to get the tuple and its options.
      line_pieces = line.split('#', 1)[0].split(None, 1)
      if not line_pieces:
        continue
      target = line_pieces[0]
      settings = json.loads(line_pieces[1]) if len(line_pieces) > 1 else {}

      if first_target:
        if settings.get('default', True):
          default_target = target
        first_target = False

      self._AddToolchain(target, setting_overrides=settings)

    if default_target:
      self._auto_default_toolchain = default_target

  def _AddToolchain(self, target, setting_overrides=None):
    """Add a toolchain to |self|.

    Args:
      target: string target (e.g. 'x86_64-cros-linux-gnu').
      setting_overrides: dictionary of setting overrides for this toolchain.
    """
    if setting_overrides is None:
      setting_overrides = dict()
    self._toolchains.append(_ToolchainTuple(
        target=target, setting_overrides=setting_overrides))

  def GetMergedToolchainSettings(self):
    """Returns a dictionary of merged toolchain settings."""
    targets = {}
    toolchains = copy.deepcopy(self._toolchains)
    if not toolchains:
      return targets

    have_default = any([setting_overrides.get(_DEFAULT_TOOLCHAIN_KEY, False)
                        for target, setting_overrides in toolchains])
    if not have_default:
      assert self._auto_default_toolchain, 'No toolchains!?'
      default_toolchain = _ToolchainTuple(self._auto_default_toolchain,
                                          {_DEFAULT_TOOLCHAIN_KEY: True})
      toolchains.insert(0, default_toolchain)

    # We might get toolchain setting overrides from a couple different overlays.
    # Merge all these overrides together, disallowing conflicts.
    for toolchain in toolchains:
      targets.setdefault(toolchain.target, dict())
      existing_overrides = targets[toolchain.target]
      for key, value in toolchain.setting_overrides.items():
        if key in existing_overrides and existing_overrides[key] != value:
          raise MismatchedToolchainConfigsError(
              'For toolchain %s, found %s to be set to both %r and %r.' %
              (toolchain.target, key, existing_overrides[key], value))
        existing_overrides[key] = value

    # Now that we've merged all the setting overrides, apply them to defaults.
    for target in targets.keys():
      settings = {
          'sdk': True,
          'crossdev': '',
          'default': False,
      }
      settings.update(targets[target])
      targets[target] = settings
    return targets
