# Status: being ported by Vladimir Prus
# Base revision: 41557
# TODO: replace the logging with dout

# Copyright Vladimir Prus 2002.
# Copyright Rene Rivera 2006.
#
# 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)

#  Manages 'generators' --- objects which can do transformation between different
#  target types and contain algorithm for finding transformation from sources
#  to targets.
#
#  The main entry point to this module is generators.construct rule. It is given
#  a list of source targets, desired target type and a set of properties.
#  It starts by selecting 'viable generators', which have any chances of producing
#  the desired target type with the required properties. Generators are ranked and
#  a set of most specific ones is selected.
# 
#  The most specific generators have their 'run' methods called, with the properties
#  and list of sources. Each one selects target which can be directly consumed, and
#  tries to convert the remaining ones to the types it can consume. This is done
#  by recursively calling 'construct' with all consumable types.
#
#  If the generator has collected all the targets it needs, it creates targets 
#  corresponding to result, and returns it. When all generators have been run,
#  results of one of them are selected and returned as result.
#
#  It's quite possible that 'construct' returns more targets that it was asked for.
#  For example, it was asked to target type EXE, but the only found generators produces
#  both EXE and TDS (file with debug) information. The extra target will be returned.
#
#  Likewise, when generator tries to convert sources to consumable types, it can get
#  more targets that it was asked for. The question is what to do with extra targets.
#  Boost.Build attempts to convert them to requested types, and attempts as early as
#  possible. Specifically, this is done after invoking each generator. (Later I'll 
#  document the rationale for trying extra target conversion at that point).
#
#  That early conversion is not always desirable. Suppose a generator got a source of
#  type Y and must consume one target of type X_1 and one target of type X_2.
#  When converting Y to X_1 extra target of type Y_2 is created. We should not try to
#  convert it to type X_1, because if we do so, the generator will get two targets
#  of type X_1, and will be at loss as to which one to use. Because of that, the
#  'construct' rule has a parameter, telling if multiple targets can be returned. If
#  the parameter is false, conversion of extra targets is not performed.


import re
import cStringIO
import os.path

from virtual_target import Subvariant
import virtual_target, type, property_set, property
from b2.util.logger import *
from b2.util.utility import *
from b2.util import set
from b2.util.sequence import unique
import b2.util.sequence as sequence
from b2.manager import get_manager

def reset ():
    """ Clear the module state. This is mainly for testing purposes.
    """
    global __generators, __type_to_generators, __generators_for_toolset, __construct_stack
    global __overrides, __active_generators
    global __viable_generators_cache, __viable_source_types_cache

    __generators = {}
    __type_to_generators = {}
    __generators_for_toolset = {}
    __overrides = {}
    
    # TODO: can these be global? 
    __construct_stack = []
    __viable_generators_cache = {}
    __viable_source_types_cache = {}
    __active_generators = []

reset ()

_re_separate_types_prefix_and_postfix = re.compile ('([^\\(]*)(\\((.*)%(.*)\\))?')
_re_match_type = re.compile('([^\\(]*)(\\(.*\\))?')


__debug = None
__indent = ""

def debug():
    global __debug
    if __debug is None:
        __debug = "--debug-generators" in bjam.variable("ARGV")        
    return __debug

def increase_indent():
    global __indent
    __indent += "    "

def decrease_indent():
    global __indent
    __indent = __indent[0:-4]

def dout(message):
    if debug():
        print __indent + message

def normalize_target_list (targets):
    """ Takes a vector of 'virtual-target' instances and makes a normalized
        representation, which is the same for given set of targets,
        regardless of their order.
    """
    return (targets[0], targets[1].sort ())


class Generator:
    """ Creates a generator.
            manager:                 the build manager.
            id:                      identifies the generator
            
            rule:                    the rule which sets up build actions.

            composing:               whether generator processes each source target in
                                     turn, converting it to required types.
                                     Ordinary generators pass all sources together to
                                     recusrive generators.construct_types call.

            source_types (optional): types that this generator can handle
    
            target_types_and_names:  types the generator will create and, optionally, names for
                                     created targets. Each element should have the form
                                         type["(" name-pattern ")"]
                                     for example, obj(%_x). Name of generated target will be found
                                     by replacing % with the name of source, provided explicit name
                                     was not specified.
    
            requirements (optional)
            
            NOTE: all subclasses must have a similar signature for clone to work!
    """
    def __init__ (self, id, composing, source_types, target_types_and_names, requirements):
        assert(not isinstance(source_types, str))
        assert(not isinstance(target_types_and_names, str))
        self.id_ = id
        self.composing_ = composing
        self.source_types_ = source_types
        self.target_types_and_names_ = target_types_and_names
        self.requirements_ = requirements
        
        self.target_types_ = []
        self.name_prefix_ = []
        self.name_postfix_ = []
        
        for e in target_types_and_names:
            # Create three parallel lists: one with the list of target types,
            # and two other with prefixes and postfixes to be added to target 
            # name. We use parallel lists for prefix and postfix (as opposed
            # to mapping), because given target type might occur several times,
            # for example "H H(%_symbols)".
            m = _re_separate_types_prefix_and_postfix.match (e)
            
            if not m:
                raise BaseException ("Invalid type and name '%s' in declaration of type '%s'" % (e, id))
            
            target_type = m.group (1)
            if not target_type: target_type = ''
            prefix = m.group (3)
            if not prefix: prefix = ''
            postfix = m.group (4)
            if not postfix: postfix = ''
            
            self.target_types_.append (target_type)
            self.name_prefix_.append (prefix)
            self.name_postfix_.append (postfix)

        for x in self.source_types_:
            type.validate (x)

        for x in self.target_types_:
            type.validate (x)

    def clone (self, new_id, new_toolset_properties):
        """ Returns another generator which differers from $(self) in
              - id
              - value to <toolset> feature in properties
        """
        return self.__class__ (new_id, 
                               self.composing_, 
                               self.source_types_, 
                               self.target_types_and_names_,
                               # Note: this does not remove any subfeatures of <toolset>
                               # which might cause problems
                               property.change (self.requirements_, '<toolset>') + new_toolset_properties)

    def clone_and_change_target_type(self, base, type):
        """Creates another generator that is the same as $(self), except that
        if 'base' is in target types of $(self), 'type' will in target types
        of the new generator."""
        target_types = []
        for t in self.target_types_and_names_:
            m = _re_match_type.match(t)
            assert m
            
            if m.group(1) == base:
                if m.group(2):
                    target_types.append(type + m.group(2))
                else:
                    target_types.append(type)
            else:
                target_types.append(t)

        return self.__class__(self.id_, self.composing_,
                              self.source_types_,
                              target_types,
                              self.requirements_)
                              

    def id (self):
        return self.id_

    def source_types (self):
        """ Returns the list of target type the generator accepts.
        """
        return self.source_types_

    def target_types (self):
        """ Returns the list of target types that this generator produces.
            It is assumed to be always the same -- i.e. it cannot change depending
            list of sources.    
        """
        return self.target_types_

    def requirements (self):
        """ Returns the required properties for this generator. Properties
            in returned set must be present in build properties if this 
            generator is to be used. If result has grist-only element,
            that build properties must include some value of that feature.
        """
        return self.requirements_

    def match_rank (self, property_set_to_match):
        """ Returns true if the generator can be run with the specified 
            properties.
        """
        # See if generator's requirements are satisfied by
        # 'properties'.  Treat a feature name in requirements
        # (i.e. grist-only element), as matching any value of the
        # feature.
        all_requirements = self.requirements ()
        
        property_requirements = []
        feature_requirements = []
        for r in all_requirements:
            if get_value (r):
                property_requirements.append (r)

            else:
                feature_requirements.append (r)

        properties_to_match = property_set_to_match.raw ()
        
        return set.contains (property_requirements, properties_to_match) \
            and set.contains (feature_requirements, get_grist (properties_to_match))
        
    def run (self, project, name, prop_set, sources):
        """ Tries to invoke this generator on the given sources. Returns a
            list of generated targets (instances of 'virtual-target').

            project:        Project for which the targets are generated.
            
            name:           Determines the name of 'name' attribute for 
                            all generated targets. See 'generated_targets' method.
                            
            prop_set:       Desired properties for generated targets.
            
            sources:        Source targets.
        """
        
        if project.manager ().logger ().on ():
            project.manager ().logger ().log (__name__, "  generator '%s'" % self.id_)
            project.manager ().logger ().log (__name__, "  composing: '%s'" % self.composing_)
        
        if not self.composing_ and len (sources) > 1 and len (self.source_types_) > 1:
            raise BaseException ("Unsupported source/source_type combination")
                
        # We don't run composing generators if no name is specified. The reason
        # is that composing generator combines several targets, which can have
        # different names, and it cannot decide which name to give for produced
        # target. Therefore, the name must be passed.
        #
        # This in effect, means that composing generators are runnable only
        # at top-level of transofrmation graph, or if name is passed explicitly.
        # Thus, we dissallow composing generators in the middle. For example, the
        # transofrmation CPP -> OBJ -> STATIC_LIB -> RSP -> EXE won't be allowed 
        # (the OBJ -> STATIC_LIB generator is composing)
        if not self.composing_ or name:
            return self.run_really (project, name, prop_set, sources)
        else:
            return []

    def run_really (self, project, name, prop_set, sources):

        # consumed: Targets that this generator will consume directly.
        # bypassed: Targets that can't be consumed and will be returned as-is.
        
        if self.composing_:
            (consumed, bypassed) = self.convert_multiple_sources_to_consumable_types (project, prop_set, sources)
        else:
            (consumed, bypassed) = self.convert_to_consumable_types (project, name, prop_set, sources)
                
        result = []
        if consumed:
            result = self.construct_result (consumed, project, name, prop_set)
            result.extend (bypassed)

        if result:
            if project.manager ().logger ().on ():
                project.manager ().logger ().log (__name__, "  SUCCESS: ", result)

        else:
                project.manager ().logger ().log (__name__, "  FAILURE")

        return result

    def construct_result (self, consumed, project, name, prop_set):
        """ Constructs the dependency graph that will be returned by this 
            generator.
                consumed:        Already prepared list of consumable targets
                                 If generator requires several source files will contain 
                                 exactly len $(self.source_types_) targets with matching types
                                 Otherwise, might contain several targets with the type of 
                                 self.source_types_ [0]
                project:
                name:
                prop_set:        Properties to be used for all actions create here
        """
        result = []
        # If this is 1->1 transformation, apply it to all consumed targets in order.
        if len (self.source_types_) < 2 and not self.composing_:

            for r in consumed:
                result.extend (self.generated_targets ([r], prop_set, project, name))

        else:

            if consumed:
                result.extend (self.generated_targets (consumed, prop_set, project, name))

        return result

    def determine_output_name(self, sources):
        """Determine the name of the produced target from the
        names of the sources."""
        
        # The simple case if when a name
        # of source has single dot. Then, we take the part before
        # dot. Several dots can be caused by:
        # - Using source file like a.host.cpp
        # - A type which suffix has a dot. Say, we can
        #   type 'host_cpp' with extension 'host.cpp'.
        # In the first case, we want to take the part till the last
        # dot. In the second case -- no sure, but for now take
        # the part till the last dot too.
        name = os.path.splitext(sources[0].name())[0]
                        
        for s in sources[1:]:
            n2 = os.path.splitext(s.name())
            if n2 != name:
                get_manager().errors()(
                    "%s: source targets have different names: cannot determine target name"
                    % (self.id_))
                        
        # Names of sources might include directory. We should strip it.        
        return os.path.basename(name)
        
        
    def generated_targets (self, sources, prop_set, project, name):
        """ Constructs targets that are created after consuming 'sources'.
            The result will be the list of virtual-target, which the same length
            as 'target_types' attribute and with corresponding types.
            
            When 'name' is empty, all source targets must have the same value of 
            the 'name' attribute, which will be used instead of the 'name' argument.
            
            The value of 'name' attribute for each generated target will be equal to
            the 'name' parameter if there's no name pattern for this type. Otherwise,
            the '%' symbol in the name pattern will be replaced with the 'name' parameter 
            to obtain the 'name' attribute.
            
            For example, if targets types are T1 and T2(with name pattern "%_x"), suffixes
            for T1 and T2 are .t1 and t2, and source if foo.z, then created files would
            be "foo.t1" and "foo_x.t2". The 'name' attribute actually determined the
            basename of a file.
            
            Note that this pattern mechanism has nothing to do with implicit patterns
            in make. It's a way to produce target which name is different for name of 
            source.
        """
        if not name:
            name = self.determine_output_name(sources)
        
        # Assign an action for each target
        action = self.action_class()        
        a = action (project.manager(), sources, self.id_, prop_set)
                
        # Create generated target for each target type.
        targets = []
        pre = self.name_prefix_
        post = self.name_postfix_
        for t in self.target_types_:
            generated_name = pre[0] + name + post[0]
            pre = pre[1:]
            post = post[1:]
            
            targets.append(virtual_target.FileTarget(generated_name, False, t, project, a))
        
        return [ project.manager().virtual_targets().register(t) for t in targets ]

    def convert_to_consumable_types (self, project, name, prop_set, sources, only_one=False):
        """ Attempts to convert 'source' to the types that this generator can
            handle. The intention is to produce the set of targets can should be
            used when generator is run.
            only_one:   convert 'source' to only one of source types
                        if there's more that one possibility, report an
                        error.
                        
            Returns a pair:
                consumed: all targets that can be consumed. 
                bypassed: all targets that cannot be consumed.
        """
        consumed = []
        bypassed = []
        missing_types = [] 

        if len (sources) > 1:
            # Don't know how to handle several sources yet. Just try 
            # to pass the request to other generator
            missing_types = self.source_types_

        else:
            (c, m) = self.consume_directly (sources [0])
            consumed += c
            missing_types += m
        
        # No need to search for transformation if
        # some source type has consumed source and
        # no more source types are needed.
        if only_one and consumed:
            missing_types = []
            
        #TODO: we should check that only one source type
        #if create of 'only_one' is true.
        # TODO: consider if consuned/bypassed separation should
        # be done by 'construct_types'.
                    
        if missing_types:
            transformed = construct_types (project, name, missing_types, prop_set, sources)
                                
            # Add targets of right type to 'consumed'. Add others to
            # 'bypassed'. The 'generators.construct' rule has done
            # its best to convert everything to the required type.
            # There's no need to rerun it on targets of different types.
                
            # NOTE: ignoring usage requirements
            for t in transformed[1]:
                if t.type() in missing_types:
                    consumed.append(t)

                else:
                    bypassed.append(t)
        
        consumed = unique(consumed)
        bypassed = unique(bypassed)
        
        # remove elements of 'bypassed' that are in 'consumed'
        
        # Suppose the target type of current generator, X is produced from 
        # X_1 and X_2, which are produced from Y by one generator.
        # When creating X_1 from Y, X_2 will be added to 'bypassed'
        # Likewise, when creating X_2 from Y, X_1 will be added to 'bypassed'
        # But they are also in 'consumed'. We have to remove them from
        # bypassed, so that generators up the call stack don't try to convert
        # them. 

        # In this particular case, X_1 instance in 'consumed' and X_1 instance
        # in 'bypassed' will be the same: because they have the same source and
        # action name, and 'virtual-target.register' won't allow two different
        # instances. Therefore, it's OK to use 'set.difference'.
        
        bypassed = set.difference(bypassed, consumed)

        return (consumed, bypassed)
    

    def convert_multiple_sources_to_consumable_types (self, project, prop_set, sources):
        """ Converts several files to consumable types.
        """        
        consumed = []
        bypassed = []

        # We process each source one-by-one, trying to convert it to
        # a usable type.
        for s in sources:
            # TODO: need to check for failure on each source.
            (c, b) = self.convert_to_consumable_types (project, None, prop_set, [s], True)
            if not c:
                project.manager ().logger ().log (__name__, " failed to convert ", s)

            consumed.extend (c)
            bypassed.extend (b)

        return (consumed, bypassed)

    def consume_directly (self, source):
        real_source_type = source.type ()

        # If there are no source types, we can consume anything
        source_types = self.source_types
        if not source_types:
            source_types = [real_source_type]

        consumed = []
        missing_types = []
        for st in self.source_types_:
            # The 'source' if of right type already)
            if real_source_type == st or type.is_derived (real_source_type, st):
                consumed.append (source)

            else:
               missing_types.append (st)
       
        return (consumed, missing_types)
    
    def action_class (self):
        """ Returns the class to be used to actions. Default implementation 
            returns "action".
        """
        return virtual_target.Action


def find (id):
    """ Finds the generator with id. Returns None if not found.
    """
    return __generators.get (id, None)

def register (g):
    """ Registers new generator instance 'g'.
    """
    id = g.id ()

    __generators [id] = g

    # A generator can produce several targets of the
    # same type. We want unique occurence of that generator
    # in .generators.$(t) in that case, otherwise, it will
    # be tried twice and we'll get false ambiguity.
    for t in sequence.unique(g.target_types()):
        __type_to_generators.setdefault(t, []).append(g)

    # Update the set of generators for toolset

    # TODO: should we check that generator with this id
    # is not already registered. For example, the fop.jam
    # module intentionally declared two generators with the
    # same id, so such check will break it.

    # Some generators have multiple periods in their name, so the
    # normal $(id:S=) won't generate the right toolset name.
    # e.g. if id = gcc.compile.c++, then
    # .generators-for-toolset.$(id:S=) will append to
    # .generators-for-toolset.gcc.compile, which is a separate
    # value from .generators-for-toolset.gcc. Correcting this
    # makes generator inheritance work properly.
    # See also inherit-generators in module toolset
    base = id.split ('.', 100) [0]

    __generators_for_toolset.setdefault(base, []).append(g)

def register_standard (id, source_types, target_types, requirements = []):
    """ Creates new instance of the 'generator' class and registers it.
        Returns the creates instance.
        Rationale: the instance is returned so that it's possible to first register
        a generator and then call 'run' method on that generator, bypassing all
        generator selection.
    """
    g = Generator (id, False, source_types, target_types, requirements)
    register (g)
    return g

def register_composing (id, source_types, target_types, requirements = []):
    g = Generator (id, True, source_types, target_types, requirements)
    register (g)
    return g

def generators_for_toolset (toolset):
    """ Returns all generators which belong to 'toolset'.
    """
    return __generators_for_toolset.get(toolset, [])

def override (overrider_id, overridee_id):
    """Make generator 'overrider-id' be preferred to
    'overridee-id'. If, when searching for generators
    that could produce a target of certain type,
    both those generators are amoung viable generators,
    the overridden generator is immediately discarded.
    
    The overridden generators are discarded immediately
    after computing the list of viable generators, before
    running any of them."""
    
    __overrides.get(overrider_id, []).append(overridee_id)

def __viable_source_types_real (target_type):
    """ Returns a list of source type which can possibly be converted
        to 'target_type' by some chain of generator invocation.
        
        More formally, takes all generators for 'target_type' and
        returns union of source types for those generators and result
        of calling itself recusrively on source types.
    """
    generators = []
        
    t = type.all_bases (target_type)
    
    result = []
    # 't' is the list of types which are not yet processed    
    while t:
        # Find all generators for current type. 
        # Unlike 'find_viable_generators' we don't care about prop_set.
        generators = __type_to_generators.get (t [0], [])
        t = t[1:]
        
        for g in generators:
            if not g.source_types():
                # Empty source types -- everything can be accepted
                result = "*"
                # This will terminate outer loop.
                t = None
                break
            
            for source_type in g.source_types ():
                if not source_type in result:
                    # If generator accepts 'source_type' it
                    # will happily accept any type derived from it
                    all = type.all_derived (source_type)
                    for n in all:
                        if not n in result:
                            t.append (n)
                            result.append (n)
        
    result = unique (result)
    
    return result


def viable_source_types (target_type):
    """ Helper rule, caches the result of '__viable_source_types_real'.
    """
    if not __viable_source_types_cache.has_key (target_type):
         __viable_source_types_cache [target_type] = __viable_source_types_real (target_type)
    return __viable_source_types_cache [target_type]

def viable_source_types_for_generator_real (generator):
    """ Returns the list of source types, which, when passed to 'run'
        method of 'generator', has some change of being eventually used
        (probably after conversion by other generators)
    """
    source_types = generator.source_types ()

    if not source_types:
        # If generator does not specify any source types,
        # it might be special generator like builtin.lib-generator
        # which just relays to other generators. Return '*' to
        # indicate that any source type is possibly OK, since we don't
        # know for sure.
        return ['*']

    else:
        result = []
        for s in source_types:
            result += type.all_derived (s) + viable_source_types (s)            
        result = unique (result)
        if "*" in result:
            result = ["*"]
        return result

def viable_source_types_for_generator (generator):
    """ Caches the result of 'viable_source_types_for_generator'.
    """
    key = str (generator)
    if not __viable_source_types_cache.has_key (key):
        __viable_source_types_cache [key] = viable_source_types_for_generator_real (generator)
    
    return __viable_source_types_cache [key]

def try_one_generator_really (project, name, generator, target_type, properties, sources):
    """ Returns usage requirements + list of created targets.
    """
    targets = generator.run (project, name, properties, sources)

    usage_requirements = []
    success = False

    dout("returned " + str(targets))

    if targets:
        success = True;
        
        if isinstance (targets[0], property_set.PropertySet):
            usage_requirements = targets [0]
            targets = targets [1]

        else:
            usage_requirements = property_set.empty ()

    dout(  "  generator" + generator.id() + " spawned ")
    #    generators.dout [ indent ] " " $(targets) ; 
#    if $(usage-requirements)
#    {
#        generators.dout [ indent ] "  with usage requirements:" $(x) ;
#    }

    if success:
        return (usage_requirements, targets)
    else:
        return None

def try_one_generator (project, name, generator, target_type, properties, sources):
    """ Checks if generator invocation can be pruned, because it's guaranteed
        to fail. If so, quickly returns empty list. Otherwise, calls
        try_one_generator_really.
    """
    source_types = []

    for s in sources:
        source_types.append (s.type ())

    viable_source_types = viable_source_types_for_generator (generator)
    
    if source_types and viable_source_types != ['*'] and\
           not set.intersection (source_types, viable_source_types):
        if project.manager ().logger ().on ():
            id = generator.id ()            
            project.manager ().logger ().log (__name__, "generator '%s' pruned" % id)
            project.manager ().logger ().log (__name__, "source_types" '%s' % source_types)
            project.manager ().logger ().log (__name__, "viable_source_types '%s'" % viable_source_types)
        
        return []

    else:
        return try_one_generator_really (project, name, generator, target_type, properties, sources)


def construct_types (project, name, target_types, prop_set, sources):
    
    result = []
    usage_requirements = property_set.empty()
    
    for t in target_types:
        r = construct (project, name, t, prop_set, sources)

        if r:
            (ur, targets) = r
            usage_requirements = usage_requirements.add(ur)
            result.extend(targets)

    # TODO: have to introduce parameter controlling if
    # several types can be matched and add appropriate
    # checks 

    # TODO: need to review the documentation for
    # 'construct' to see if it should return $(source) even
    # if nothing can be done with it. Currents docs seem to
    # imply that, contrary to the behaviour.
    if result:
        return (usage_requirements, result)

    else:
        return (usage_requirements, sources)

def __ensure_type (targets):
    """ Ensures all 'targets' have types. If this is not so, exists with 
        error.
    """
    for t in targets:
        if not t.type ():
            raise BaseException ("target '%s' has no type" % str (t))

def find_viable_generators_aux (target_type, prop_set):
    """ Returns generators which can be used to construct target of specified type
        with specified properties. Uses the following algorithm:
        - iterates over requested target_type and all it's bases (in the order returned bt
          type.all-bases.
        - for each type find all generators that generate that type and which requirements
          are satisfied by properties.
        - if the set of generators is not empty, returns that set.
        
        Note: this algorithm explicitly ignores generators for base classes if there's
        at least one generator for requested target_type.
    """
    # Select generators that can create the required target type.
    viable_generators = []
    initial_generators = []

    import type

    # Try all-type generators first. Assume they have
    # quite specific requirements.
    all_bases = type.all_bases(target_type)
        
    for t in all_bases:
        
        initial_generators = __type_to_generators.get(t, [])
        
        if initial_generators:
            dout("there are generators for this type")
            if t != target_type:
                # We're here, when no generators for target-type are found,
                # but there are some generators for a base type.
                # We'll try to use them, but they will produce targets of
                # base type, not of 'target-type'. So, we clone the generators
                # and modify the list of target types.
                generators2 = []
                for g in initial_generators[:]:
                    # generators.register adds generator to the list of generators
                    # for toolsets, which is a bit strange, but should work.
                    # That list is only used when inheriting toolset, which
                    # should have being done before generators are run.
                    ng = g.clone_and_change_target_type(t, target_type)
                    generators2.append(ng)
                    register(ng)
                    
                initial_generators = generators2
            break
    
    for g in initial_generators:
        dout("trying generator " + g.id()
             + "(" + str(g.source_types()) + "->" + str(g.target_types()) + ")")
        
        m = g.match_rank(prop_set)
        if m:
            dout("  is viable")
            viable_generators.append(g)
                            
    return viable_generators

def find_viable_generators (target_type, prop_set):
    key = target_type + '.' + str (prop_set)

    l = __viable_generators_cache.get (key, None)

    if not l:
        l = find_viable_generators_aux (target_type, prop_set)

        __viable_generators_cache [key] = l

    viable_generators = []
    for g in l:
        # Avoid trying the same generator twice on different levels.
        # TODO: is this really used?
        if not g in __active_generators:
            viable_generators.append (g)

    # Generators which override 'all'.
    all_overrides = []
    
    # Generators which are overriden
    overriden_ids = [] 
       
    for g in viable_generators:
        id = g.id ()
        
        this_overrides = __overrides.get (id, [])
        
        if this_overrides:
            overriden_ids.extend (this_overrides)
            if 'all' in this_overrides:
                all_overrides.append (g)

    if all_overrides:
        viable_generators = all_overrides

    result = []
    for g in viable_generators:
        if not g.id () in overriden_ids:
            result.append (g)
        
    return result
    
def __construct_really (project, name, target_type, prop_set, sources):
    """ Attempts to construct target by finding viable generators, running them
        and selecting the dependency graph.
    """
    viable_generators = find_viable_generators (target_type, prop_set)
                    
    result = []
    
    project.manager ().logger ().log (__name__, "*** %d viable generators" % len (viable_generators))

    generators_that_succeeded = []
    
    for g in viable_generators:
        __active_generators.append(g)        
        r = try_one_generator (project, name, g, target_type, prop_set, sources)
        del __active_generators[-1]
        
        if r:
            generators_that_succeeded.append(g)
            if result:
                output = cStringIO.StringIO()
                print >>output, "ambiguity found when searching for best transformation"
                print >>output, "Trying to produce type '%s' from: " % (target_type)
                for s in sources:
                    print >>output, " - " + s.str()
                print >>output, "Generators that succeeded:"
                for g in generators_that_succeeded:
                    print >>output, " - " + g.id()
                print >>output, "First generator produced: "
                for t in result[1:]:
                    print >>output, " - " + str(t)
                print >>output, "Second generator produced:"
                for t in r[1:]:
                    print >>output, " - " + str(t)
                get_manager().errors()(output.getvalue())
            else:
                result = r;
            
    return result;


def construct (project, name, target_type, prop_set, sources):
    """ Attempts to create target of 'target-type' with 'properties'
        from 'sources'. The 'sources' are treated as a collection of
        *possible* ingridients -- i.e. it is not required to consume
        them all. If 'multiple' is true, the rule is allowed to return
        several targets of 'target-type'.          
        
        Returns a list of target. When this invocation is first instance of
        'construct' in stack, returns only targets of requested 'target-type',
        otherwise, returns also unused sources and additionally generated
        targets.            
    """
    # TODO: Why is global needed here?
    global __construct_stack
    if __construct_stack:
        __ensure_type (sources)
        
    __construct_stack.append (1)

    if project.manager().logger().on():
        increase_indent ()
        
        dout( "*** construct " + target_type)
        
        for s in sources:
            dout("    from " + str(s))

        project.manager().logger().log (__name__, "    properties: ", prop_set.raw ())
             
    result = __construct_really(project, name, target_type, prop_set, sources)

    project.manager().logger().decrease_indent()
        
    __construct_stack = __construct_stack [1:]

    return result
    
