# Copyright Pedro Ferreira 2005.
# Copyright Vladimir Prus 2007.
# Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

bjam_interface = __import__('bjam')

import operator

class BjamAction:
    """Class representing bjam action defined from Python."""
    
    def __init__(self, action_name, function):
        self.action_name = action_name
        self.function = function
            
    def __call__(self, targets, sources, property_set):
        if self.function:
            self.function(targets, sources, property_set)
        # Bjam actions defined from Python have only the command
        # to execute, and no associated jam procedural code. So
        # passing 'property_set' to it is not necessary.
        bjam_interface.call("set-update-action", self.action_name,
                            targets, sources, [])

class BjamNativeAction:
    """Class representing bjam action fully defined by Jam code."""
    
    def __init__(self, action_name):
        self.action_name = action_name
        
    def __call__(self, targets, sources, property_set):
        if property_set:
            bjam_interface.call("set-update-action", self.action_name,
                                targets, sources, property_set.raw())
        else:
            bjam_interface.call("set-update-action", self.action_name,
                                targets, sources, [])
        
action_modifiers = {"updated": 0x01,
                    "together": 0x02,
                    "ignore": 0x04,
                    "quietly": 0x08,
                    "piecemeal": 0x10,
                    "existing": 0x20}

class Engine:
    """ The abstract interface to a build engine.

    For now, the naming of targets, and special handling of some
    target variables like SEARCH and LOCATE make this class coupled
    to bjam engine.
    """
    def __init__ (self):
        self.actions = {}

    def add_dependency (self, targets, sources):
        """Adds a dependency from 'targets' to 'sources'

        Both 'targets' and 'sources' can be either list
        of target names, or a single target name.
        """
        if isinstance (targets, str):
            targets = [targets]
        if isinstance (sources, str):
            sources = [sources]

        for target in targets:
            for source in sources:
                self.do_add_dependency (target, source)
    
    def set_target_variable (self, targets, variable, value, append=0):
        """ Sets a target variable.

        The 'variable' will be available to bjam when it decides
        where to generate targets, and will also be available to
        updating rule for that 'taret'.
        """
        if isinstance (targets, str): 
            targets = [targets]

        for target in targets:
            self.do_set_target_variable (target, variable, value, append)

    def set_update_action (self, action_name, targets, sources, properties):
        """ Binds a target to the corresponding update action.
            If target needs to be updated, the action registered
            with action_name will be used.
            The 'action_name' must be previously registered by
            either 'register_action' or 'register_bjam_action'
            method.
        """
        if isinstance (targets, str): 
            targets = [targets]
        self.do_set_update_action (action_name, targets, sources, properties)

    def register_action (self, action_name, command, bound_list = [], flags = [],
                         function = None):
        """Creates a new build engine action.

        Creates on bjam side an action named 'action_name', with
        'command' as the command to be executed, 'bound_variables'
        naming the list of variables bound when the command is executed
        and specified flag.
        If 'function' is not None, it should be a callable taking three
        parameters:
            - targets
            - sources
            - instance of the property_set class
        This function will be called by set_update_action, and can
        set additional target variables.
        """
        if self.actions.has_key(action_name):
            raise "Bjam action %s is already defined" % action_name

        assert(isinstance(flags, list))

        bjam_flags = reduce(operator.or_,
                            (action_modifiers[flag] for flag in flags), 0)

        bjam_interface.define_action(action_name, command, bound_list, bjam_flags)

        self.actions[action_name] = BjamAction(action_name, function)

    def register_bjam_action (self, action_name):
        """Informs self that 'action_name' is declared in bjam.

        From this point, 'action_name' is a valid argument to the
        set_update_action method. The action_name should be callable
        in the global module of bjam.
        """

        # We allow duplicate calls to this rule for the same
        # action name.  This way, jamfile rules that take action names
        # can just register them without specially checking if
        # action is already registered.
        if not self.actions.has_key(action_name):
            self.actions[action_name] = BjamNativeAction(action_name)
    
    # Overridables


    def do_set_update_action (self, action_name, targets, sources, property_set):
        action = self.actions.get(action_name)
        if not action:
            raise "No action %s was registered" % action_name
        action(targets, sources, property_set)

    def do_set_target_variable (self, target, variable, value, append):
        if append:
            bjam_interface.call("set-target-variable", target, variable, value, "true")
        else:
            bjam_interface.call("set-target-variable", target, variable, value)
        
    def do_add_dependency (self, target, source):
        bjam_interface.call("DEPENDS", target, source)
         
        
