#
#  Copyright (C) 2016 Codethink Limited
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU Lesser General Public
#  License as published by the Free Software Foundation; either
#  version 2 of the License, or (at your option) any later version.
#
#  This library is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
#  Lesser General Public License for more details.
#
#  You should have received a copy of the GNU Lesser General Public
#  License along with this library. If not, see <http://www.gnu.org/licenses/>.
#
#  Authors:
#        Tristan Van Berkom <tristan.vanberkom@codethink.co.uk>

import os
from typing import Tuple, Type, Iterator
from pluginbase import PluginSource

from .. import utils
from .. import _site
from ..plugin import Plugin
from ..source import Source
from ..element import Element
from ..node import Node
from ..utils import UtilError
from .._exceptions import PluginError
from .._messenger import Messenger
from .._message import Message, MessageType

from .pluginorigin import PluginOrigin, PluginType


# A Context for loading plugin types
#
# Args:
#     plugin_base (PluginBase): The main PluginBase object to work with
#     plugin_type (PluginType): The type of plugin to load
#
# Since multiple pipelines can be processed recursively
# within the same interpretor, it's important that we have
# one context associated to the processing of a given pipeline,
# this way sources and element types which are particular to
# a given BuildStream project are isolated to their respective
# Pipelines.
#
class PluginFactory:
    def __init__(self, plugin_base, plugin_type):

        # For pickling across processes, make sure this context has a unique
        # identifier, which we prepend to the identifier of each PluginSource.
        # This keeps plugins loaded during the first and second pass distinct
        # from eachother.
        self._identifier = str(id(self))

        self._plugin_type = plugin_type  # The kind of plugins this factory loads
        self._types = {}  # Plugin type lookup table by kind
        self._origins = {}  # PluginOrigin lookup table by kind
        self._allow_deprecated = {}  # Lookup table to check if a plugin is allowed to be deprecated

        self._plugin_base = plugin_base  # The PluginBase object

        # The PluginSource objects need to be kept in scope for the lifetime
        # of the loaded plugins, otherwise the PluginSources delete the plugin
        # modules when they go out of scope.
        #
        # FIXME: Instead of keeping this table, we can call:
        #
        #            PluginBase.make_plugin_source(..., persist=True)
        #
        #        The persist attribute avoids this behavior. This is not currently viable
        #        because the BuildStream data model (projects and elements) does not properly
        #        go out of scope when the CLI completes, causing errors to occur when
        #        invoking BuildStream multiple times during tests.
        #
        self._sources = {}  #  A mapping of (location, kind) -> PluginSource objects

        self._init_site_source()

    # Initialize the PluginSource object for core plugins
    def _init_site_source(self):
        if self._plugin_type == PluginType.SOURCE:
            self._site_plugins_path = _site.source_plugins
        elif self._plugin_type == PluginType.ELEMENT:
            self._site_plugins_path = _site.element_plugins

        self._site_source = self._plugin_base.make_plugin_source(
            searchpath=[self._site_plugins_path], identifier=self._identifier + "site",
        )

    ######################################################
    #                  Public Methods                    #
    ######################################################

    # register_plugin_origin():
    #
    # Registers the PluginOrigin to use for the given plugin kind
    #
    # Args:
    #    kind (str): The kind identifier of the Plugin
    #    origin (PluginOrigin): The PluginOrigin providing the plugin
    #    allow_deprecated (bool): Whether this plugin kind is allowed to be used in a deprecated state
    #
    def register_plugin_origin(self, kind: str, origin: PluginOrigin, allow_deprecated: bool):
        if kind in self._origins:
            raise PluginError(
                "More than one {} plugin registered as kind '{}'".format(self._plugin_type, kind),
                reason="duplicate-plugin",
            )

        self._origins[kind] = origin
        self._allow_deprecated[kind] = allow_deprecated

    # lookup():
    #
    # Fetches a type loaded from a plugin in this plugin context
    #
    # Args:
    #     messenger (Messenger): The messenger
    #     kind (str): The kind of Plugin to create
    #     provenance_node (Node): The node from where the plugin was referenced
    #
    # Returns:
    #     (type): The type associated with the given kind
    #     (str): A path to the YAML file holding the plugin's defaults, or None
    #
    # Raises: PluginError
    #
    def lookup(self, messenger: Messenger, kind: str, provenance_node: Node) -> Tuple[Type[Plugin], str]:
        plugin_type, defaults = self._ensure_plugin(kind, provenance_node)

        # We can be called with None for the messenger here in the
        # case that we've been pickled through the scheduler (see jobpickler.py),
        #
        # In this case we know that we've already initialized and do not need
        # to warn about deprecated plugins a second time.
        if messenger is None:
            return plugin_type, defaults

        # After looking up the type, issue a warning if it's deprecated
        #
        # We do this here because we want to issue one warning for each time the
        # plugin is used.
        #
        if plugin_type.BST_PLUGIN_DEPRECATED and not self._allow_deprecated[kind]:
            message = Message(
                MessageType.WARN,
                "{}: Using deprecated plugin '{}'".format(provenance_node.get_provenance(), kind),
                detail=plugin_type.BST_PLUGIN_DEPRECATION_MESSAGE,
            )
            messenger.message(message)

        return plugin_type, defaults

    # list_plugins():
    #
    # A generator which yields all of the plugins which have been loaded
    #
    # Yields:
    #    (str): The plugin kind
    #    (type): The loaded plugin type
    #    (str): The default yaml file, if any
    #    (str): The display string describing how the plugin was loaded
    #
    def list_plugins(self) -> Iterator[Tuple[str, Type[Plugin], str, str]]:
        for kind, (plugin_type, defaults, display) in self._types.items():
            yield kind, plugin_type, defaults, display

    # get_plugin_paths():
    #
    # Gets the directory on disk where the plugin itself is located,
    # and a full path to the plugin's accompanying YAML file for
    # it's defaults (if any).
    #
    # Args:
    #    kind (str): The plugin kind
    #
    # Returns:
    #    (str): The full path to the directory containing the plugin
    #    (str): The full path to the accompanying .yaml file containing
    #           the plugin's preferred defaults.
    #    (str): The explanatory display string describing how this plugin was loaded
    #
    def get_plugin_paths(self, kind: str):
        try:
            origin = self._origins[kind]
        except KeyError:
            return None, None, None

        return origin.get_plugin_paths(kind, self._plugin_type)

    ######################################################
    #                 Private Methods                    #
    ######################################################

    # _ensure_plugin():
    #
    # Ensures that a plugin is loaded, delegating the work of getting
    # the plugin materials from the respective PluginOrigin
    #
    # Args:
    #    kind (str): The plugin kind to load
    #    provenance (str): The provenance of whence the plugin was referred to in the project
    #
    # Returns:
    #    (type): The loaded type
    #    (str): The full path the the yaml file containing defaults, or None
    #
    # Raises:
    #    (PluginError): In case something went wrong loading the plugin
    #
    def _ensure_plugin(self, kind: str, provenance_node: Node) -> Tuple[Type[Plugin], str]:

        if kind not in self._types:

            # Get the directory on disk where the plugin exists, and
            # the optional accompanying .yaml file for the plugin, should
            # one have been provided.
            #
            location, defaults, display = self.get_plugin_paths(kind)

            if location:

                # Make the PluginSource object
                #
                source = self._plugin_base.make_plugin_source(
                    searchpath=[location], identifier=self._identifier + location + kind,
                )

                # Keep a reference on the PluginSources (see comment in __init__)
                #
                self._sources[(location, kind)] = source
            else:
                # Try getting it from the core plugins
                if kind not in self._site_source.list_plugins():
                    raise PluginError(
                        "{}: No {} plugin registered for kind '{}'".format(
                            provenance_node.get_provenance(), self._plugin_type, kind
                        ),
                        reason="plugin-not-found",
                    )

                source = self._site_source
                defaults = os.path.join(self._site_plugins_path, "{}.yaml".format(kind))
                if not os.path.exists(defaults):
                    defaults = None
                display = "core plugin"

            self._types[kind] = (self._load_plugin(source, kind), defaults, display)

        type_, defaults, _ = self._types[kind]
        return type_, defaults

    # _load_plugin():
    #
    # Loads the actual plugin type from the PluginSource
    #
    # Args:
    #    source (PluginSource): The PluginSource
    #    kind (str): The plugin kind to load
    #
    # Returns:
    #    (type): The loaded type
    #
    # Raises:
    #    (PluginError): In case something went wrong loading the plugin
    #
    def _load_plugin(self, source: PluginSource, kind: str) -> Type[Plugin]:

        try:
            plugin = source.load_plugin(kind)

        except ImportError as e:
            raise PluginError("Failed to load {} plugin '{}': {}".format(self._plugin_type, kind, e)) from e

        try:
            plugin_type = plugin.setup()
        except AttributeError as e:
            raise PluginError(
                "{} plugin '{}' did not provide a setup() function".format(self._plugin_type, kind),
                reason="missing-setup-function",
            ) from e
        except TypeError as e:
            raise PluginError(
                "setup symbol in {} plugin '{}' is not a function".format(self._plugin_type, kind),
                reason="setup-is-not-function",
            ) from e

        self._assert_plugin(kind, plugin_type)
        self._assert_min_version(kind, plugin_type)

        return plugin_type

    # _assert_plugin():
    #
    # Performs assertions on the loaded plugin
    #
    # Args:
    #    kind (str): The plugin kind to load
    #    plugin_type (type): The loaded plugin type
    #
    # Raises:
    #    (PluginError): In case something went wrong loading the plugin
    #
    def _assert_plugin(self, kind: str, plugin_type: Type[Plugin]):
        if kind in self._types:
            raise PluginError(
                "Tried to register {} plugin for existing kind '{}' "
                "(already registered {})".format(self._plugin_type, kind, self._types[kind].__name__)
            )

        base_type: Type[Plugin]
        if self._plugin_type == PluginType.SOURCE:
            base_type = Source
        elif self._plugin_type == PluginType.ELEMENT:
            base_type = Element

        try:
            if not issubclass(plugin_type, base_type):
                raise PluginError(
                    "{} plugin '{}' returned type '{}', which is not a subclass of {}".format(
                        self._plugin_type, kind, plugin_type.__name__, base_type.__name__
                    ),
                    reason="setup-returns-bad-type",
                )
        except TypeError as e:
            raise PluginError(
                "{} plugin '{}' returned something that is not a type (expected subclass of {})".format(
                    self._plugin_type, kind, self._plugin_type
                ),
                reason="setup-returns-not-type",
            ) from e

    # _assert_min_version():
    #
    # Performs the version checks on the loaded plugin type,
    # ensuring that the loaded plugin is intended to work
    # with this version of BuildStream.
    #
    # Args:
    #    kind (str): The plugin kind to load
    #    plugin_type (type): The loaded plugin type
    #
    # Raises:
    #    (PluginError): In case something went wrong loading the plugin
    #
    def _assert_min_version(self, kind, plugin_type):

        if plugin_type.BST_MIN_VERSION is None:
            raise PluginError(
                "{} plugin '{}' did not specify BST_MIN_VERSION".format(self._plugin_type, kind),
                reason="missing-min-version",
                detail="Are you trying to use a BuildStream 1 plugin with a BuildStream 2 project ?",
            )

        try:
            min_version_major, min_version_minor = utils._parse_version(plugin_type.BST_MIN_VERSION)
        except UtilError as e:
            raise PluginError(
                "{} plugin '{}' specified malformed BST_MIN_VERSION: {}".format(
                    self._plugin_type, kind, plugin_type.BST_MIN_VERSION
                ),
                reason="malformed-min-version",
                detail="BST_MIN_VERSION must be specified as 'MAJOR.MINOR' with "
                + "numeric major and minor minimum required version numbers",
            ) from e

        bst_major, bst_minor = utils._get_bst_api_version()

        if min_version_major != bst_major:
            raise PluginError(
                "{} plugin '{}' requires BuildStream {}, but is being loaded with BuildStream {}".format(
                    self._plugin_type, kind, min_version_major, bst_major
                ),
                reason="incompatible-major-version",
                detail="You will need to find the correct version of this plugin for your project.",
            )

        if min_version_minor > bst_minor:
            raise PluginError(
                "{} plugin '{}' requires BuildStream {}, but is being loaded with BuildStream {}.{}".format(
                    self._plugin_type, kind, plugin_type.BST_MIN_VERSION, bst_major, bst_minor
                ),
                reason="incompatible-minor-version",
                detail="Please upgrade to BuildStream {}".format(plugin_type.BST_MIN_VERSION),
            )
