""" surl.plugins """

# Copyright (c) 2009-2010 Ahmed El-Mahdawy <aa.mahdawy.10@gmail.com>
# Copyright (c) 2009 Savvas Radevic <vicedar@gmail.com>
#
# 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, either version 3 of the License, or
# (at your option) any later version.
#
# 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, see <http://www.gnu.org/licenses/>.

import sys
import imp
from ctypes import *
import os.path
import dirs

def read_plugin_lst():
    """ Reads plugin.lst.
        Returns: a list item with the plugin paths
    """
    plugin_paths_common = list()
    plugin_paths_surl = list()
    plugin_paths_user = list()

    # Surl directory: <surl dir>/plugin.lst
    #print("Read surl/plugin.lst file: %s" % (dirs.surl_plugin_lst))
    if os.path.exists(dirs.surl_plugin_lst):
        plugin_file_surl = open(dirs.surl_plugin_lst)
        x = plugin_file_surl.read()
        plugin_paths_surl = x.splitlines()

    # User directory: ~/.surl/plugin.lst
    #print("Read ~/.surl/plugin.lst file: %s" % (dirs.surl_plugin_lst))
    if os.path.exists(dirs.user_plugin_lst):
        plugin_file_user = open(dirs.user_plugin_lst)
        x = plugin_file_user.read()
        plugin_paths_user = x.splitlines()

    # Merging will ignore duplicate plugin file path listings
    # Combine/Merge plugin_lst_surl and plugin_lst_user lists into one,
    # making a list with *unique* listings of plugin file paths.
    #print("Process paths from surl/plugin.lst: %s" % (plugin_paths_surl)
    for l in plugin_paths_surl:
        #print("surl/plugin.lst: %s" % (l))
        if not l.startswith("#") and not l.strip() == "" and not l == "\n":
            abs_path = dirs.get_real_path(l)
            try: # Check if it's in plugin_paths_common list
                plugin_paths_common.index(abs_path)
            except ValueError:
                plugin_paths_common.append(abs_path) # Append it if not in plugin_paths list

    #print("Process paths from ~/.surl/plugin.lst: %s" % (plugin_paths_user)
    for l in plugin_paths_user:
        if not l.startswith("#") and not l.strip() == "" and not l == "\n":
            abs_path = dirs.get_real_path(l)
            try: # Check if it's in plugin_paths_common list
                plugin_paths_common.index(abs_path)
            except ValueError:
                plugin_paths_common.append(abs_path) # Append it if not in plugin_paths list

    #print("plugin_paths_common: %s" % (plugin_paths_common))
    return plugin_paths_common

def load(plugin_paths):
    """ Load plugins from plugin_paths """
    global plugins

    # [x][0]: plugin type (1 = compiled library, 0 = python script)
    # [x][1]: either a CDLL object or module, depending on the plugin type
    #print("TEST: surl.plugins.load()")
    plugins = list()

    # Read plugin paths and detect types
    # TODO: detect plugin types depending on data, not file extension
    for plugin in plugin_paths:
        if os.path.exists(plugin):
            if plugin.endswith(".py"): # python script
                plugins.append([0, imp.load_source("surlplugin", plugin)])
            elif plugin.endswith(".so") or plugin.endswith(".dll"): # library
                plugins.append([1, CDLL(plugin)])
            else:
                print "WARNING: Plugin %s has an unknown file type" % (plugin)
                print "WARNING: Known file types are .py, .so, and .dll"
        else:
            print "WARNING: Could not find plugin %s" % (plugin)
    
    # Call Load() functions
    for plugin in plugins:
        try:
            plugin[1].Load(" ".join(["%s" % val for val in sys.argv]))
        except Exception:
            print "WARNING: Unable to call Load() for " + str(plugin)

def unload():
    global plugins
    
    for plugin in plugins:
        try:
            plugin.Unload()
        except AttributeError:
            print "WARNING: Unable to call Unload() for " + str(plugin)
        plugin = None

def call(function):
    global plugins
    
    for plugin in plugins:
        try:
            exec("plugin[1]." + function)
        except AttributeError:
            print "WARNING: Unable to call %s for %s" % (function, str(plugin))
