#!/usr/bin/env python -tt
#
# Copyright (c) 2011 Intel, Inc.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; version 2 of the License
#
# This program 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 General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc., 59
# Temple Place - Suite 330, Boston, MA 02111-1307, USA.

__all__ = ['ImagerPlugin', 'SourcePlugin']

import os
import logging

from collections import defaultdict
from importlib.machinery import SourceFileLoader

from wic import WicError
from wic.misc import get_bitbake_var

PLUGIN_TYPES = ["imager", "source"]

SCRIPTS_PLUGIN_DIR = "scripts/lib/wic/plugins"

logger = logging.getLogger('wic')

PLUGINS = defaultdict(dict)

class PluginMgr:
    _plugin_dirs = []

    @classmethod
    def get_plugins(cls, ptype):
        """Get dictionary of <plugin_name>:<class> pairs."""
        if ptype not in PLUGIN_TYPES:
            raise WicError('%s is not valid plugin type' % ptype)

        # collect plugin directories
        if not cls._plugin_dirs:
            cls._plugin_dirs = [os.path.join(os.path.dirname(__file__), 'plugins')]
            layers = get_bitbake_var("BBLAYERS") or ''
            for layer_path in layers.split():
                path = os.path.join(layer_path, SCRIPTS_PLUGIN_DIR)
                path = os.path.abspath(os.path.expanduser(path))
                if path not in cls._plugin_dirs and os.path.isdir(path):
                    cls._plugin_dirs.insert(0, path)

        if ptype not in PLUGINS:
            # load all ptype plugins
            for pdir in cls._plugin_dirs:
                ppath = os.path.join(pdir, ptype)
                if os.path.isdir(ppath):
                    for fname in os.listdir(ppath):
                        if fname.endswith('.py'):
                            mname = fname[:-3]
                            mpath = os.path.join(ppath, fname)
                            logger.debug("loading plugin module %s", mpath)
                            SourceFileLoader(mname, mpath).load_module()

        return PLUGINS.get(ptype)

class PluginMeta(type):
    def __new__(cls, name, bases, attrs):
        class_type = type.__new__(cls, name, bases, attrs)
        if 'name' in attrs:
            PLUGINS[class_type.wic_plugin_type][attrs['name']] = class_type

        return class_type

class ImagerPlugin(metaclass=PluginMeta):
    wic_plugin_type = "imager"

    def do_create(self):
        raise WicError("Method %s.do_create is not implemented" %
                       self.__class__.__name__)

class SourcePlugin(metaclass=PluginMeta):
    wic_plugin_type = "source"
    """
    The methods that can be implemented by --source plugins.

    Any methods not implemented in a subclass inherit these.
    """

    @classmethod
    def do_install_disk(cls, disk, disk_name, creator, workdir, oe_builddir,
                        bootimg_dir, kernel_dir, native_sysroot):
        """
        Called after all partitions have been prepared and assembled into a
        disk image.  This provides a hook to allow finalization of a
        disk image e.g. to write an MBR to it.
        """
        logger.debug("SourcePlugin: do_install_disk: disk: %s", disk_name)

    @classmethod
    def do_stage_partition(cls, part, source_params, creator, cr_workdir,
                           oe_builddir, bootimg_dir, kernel_dir,
                           native_sysroot):
        """
        Special content staging hook called before do_prepare_partition(),
        normally empty.

        Typically, a partition will just use the passed-in parame e.g
        straight bootimg_dir, etc, but in some cases, things need to
        be more tailored e.g. to use a deploy dir + /boot, etc.  This
        hook allows those files to be staged in a customized fashion.
        Not that get_bitbake_var() allows you to acces non-standard
        variables that you might want to use for this.
        """
        logger.debug("SourcePlugin: do_stage_partition: part: %s", part)

    @classmethod
    def do_configure_partition(cls, part, source_params, creator, cr_workdir,
                               oe_builddir, bootimg_dir, kernel_dir,
                               native_sysroot):
        """
        Called before do_prepare_partition(), typically used to create
        custom configuration files for a partition, for example
        syslinux or grub config files.
        """
        logger.debug("SourcePlugin: do_configure_partition: part: %s", part)

    @classmethod
    def do_prepare_partition(cls, part, source_params, creator, cr_workdir,
                             oe_builddir, bootimg_dir, kernel_dir, rootfs_dir,
                             native_sysroot):
        """
        Called to do the actual content population for a partition i.e. it
        'prepares' the partition to be incorporated into the image.
        """
        logger.debug("SourcePlugin: do_prepare_partition: part: %s", part)
