# Copyright 2003 Rene Rivera
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)

# Modifiers are generalized generators that mutate targets in specific ways.
# This structure allows for grouping a variety of functionality in an
# orthogonal way to the functionality in toolsets, and without specifying
# more target variations. In turn the modifiers can be used as building
# blocks to implement simple requests, like the <version> feature.

import modules ;
import feature ;
import errors ;
import type ;
import "class" : new ;
import generators ;
import property ;
import virtual-target ;
import numbers ;
import sequence ;
import symlink ;
import property-set ;

# Base generator for creating targets that are modifications of existing
# targets.
#
class modifier : generator
{
    rule __init__ (
        id
        composing ?
        : source-types *
        : target-types-and-names +
        : requirements *
        )
    {
        generator.__init__ $(id) $(composing)
            : $(source-types)
            : $(target-types-and-names)
            : $(requirements) ;

        self.targets-in-progress = ;
    }

    # Wraps the generation of the target to call before and after rules to
    # affect the real target.
    #
    rule run ( project name ? : property-set : sources + )
    {
        local result ;
        local current-target = $(project)^$(name) ;
        if ! $(current-target) in $(self.targets-in-progress)
        {
            # Before modifications...
            local project_ =
                [ modify-project-before
                    $(project) $(name) : $(property-set) : $(sources) ] ;
            local name_ =
                [ modify-name-before
                    $(project) $(name) : $(property-set) : $(sources) ] ;
            local property-set_ =
                [ modify-properties-before
                    $(project) $(name) : $(property-set) : $(sources) ] ;
            local sources_ =
                [ modify-sources-before
                    $(project) $(name) : $(property-set) : $(sources) ] ;
            project = $(project_) ;
            name = $(name_) ;
            property-set = $(property-set_) ;
            sources = $(sources_) ;

            # Generate the real target...
            local target-type-p =
                [ property.select <main-target-type> : [ $(property-set).raw ] ] ;
            self.targets-in-progress += $(current-target) ;
            result =
                [ generators.construct $(project) $(name)
                    : $(target-type-p:G=)
                    : $(property-set)
                    : $(sources) ] ;
            self.targets-in-progress = $(self.targets-in-progress[1--2]) ;

            # After modifications...
            result =
                [ modify-target-after $(result)
                    : $(project) $(name)
                    : $(property-set)
                    : $(sources) ] ;
        }
        return $(result) ;
    }

    rule modify-project-before ( project name ? : property-set : sources + )
    {
        return $(project) ;
    }

    rule modify-name-before ( project name ? : property-set : sources + )
    {
        return $(name) ;
    }

    rule modify-properties-before ( project name ? : property-set : sources + )
    {
        return $(property-set) ;
    }

    rule modify-sources-before ( project name ? : property-set : sources + )
    {
        return $(sources) ;
    }

    rule modify-target-after ( target : project name ? : property-set : sources + )
    {
        return $(target) ;
    }

    # Utility, clones a file-target with optional changes to the name, type and
    # project of the target.
    # NOTE: This functionality should be moved, and generalized, to
    # virtual-targets.
    #
    rule clone-file-target ( target : new-name ? : new-type ? : new-project ? )
    {
        # Need a MUTCH better way to clone a target...
        new-name ?= [ $(target).name ] ;
        new-type ?= [ $(target).type ] ;
        new-project ?= [ $(target).project ] ;
        local result = [ new file-target $(new-name) : $(new-type) : $(new-project) ] ;

        if [ $(target).dependencies ] { $(result).depends [ $(target).dependencies ] ; }
        $(result).root [ $(target).root ] ;
        $(result).set-usage-requirements [ $(target).usage-requirements ] ;

        local action = [ $(target).action ] ;
        local action-class = [ modules.peek $(action) : __class__ ] ;

        local ps = [ $(action).properties ] ;
        local cloned-action = [ new $(action-class) $(result) :
          [ $(action).sources ] : [ $(action).action-name ] : $(ps) ] ;
        $(result).action $(cloned-action) ;

        return $(result) ;
    }
}


# A modifier that changes the name of a target, after it's generated, given a
# regular expression to split the name, and a set of token to insert between the
# split tokens of the name. This also exposes the target for other uses with a
# symlink to the original name (optionally).
#
class name-modifier : modifier
{
    rule __init__ ( )
    {
        # Apply ourselves to EXE targets, for now.
        modifier.__init__ name.modifier : : EXE LIB : <name-modify>yes ;
    }

    # Modifies the name, by cloning the target with the new name.
    #
    rule modify-target-after ( target : project name ? : property-set : sources + )
    {
        local result = $(target) ;

        local name-mod-p = [ property.select <name-modifier> : [ $(property-set).raw ] ] ;
        if $(name-mod-p)
        {
            local new-name = [ modify-name [ $(target).name ] : $(name-mod-p:G=) ] ;
            if $(new-name) != [ $(target).name ]
            {
                result = [ clone-file-target $(target) : $(new-name) ] ;
            }
            local expose-original-as-symlink = [ MATCH "<symlink>(.*)" : $(name-mod-p) ] ;
            if $(expose-original-as-symlink)
            {
                local symlink-t = [ new symlink-targets $(project) : $(name) : [ $(result).name ] ] ;
                result = [ $(symlink-t).construct $(result)
                    : [ property-set.create [ $(property-set).raw ] <symlink-location>build-relative ] ] ;
            }
        }

        return $(result) ;
    }

    # Do the transformation of the name.
    #
    rule modify-name ( name : modifier-spec + )
    {
        local match = [ MATCH "<match>(.*)" : $(modifier-spec) ] ;
        local name-parts = [ MATCH $(match) : $(name) ] ;
        local insertions = [ sequence.insertion-sort [ MATCH "(<[0123456789]+>.*)" : $(modifier-spec) ] ] ;
        local new-name-parts ;
        local insert-position = 1 ;
        while $(insertions)
        {
            local insertion = [ MATCH "<$(insert-position)>(.*)" : $(insertions[1]) ] ;
            if $(insertion)
            {
                new-name-parts += $(insertion) ;
                insertions = $(insertions[2-]) ;
            }
            new-name-parts += $(name-parts[1]) ;
            name-parts = $(name-parts[2-]) ;
            insert-position = [ numbers.increment $(insert-position) ] ;
        }
        new-name-parts += $(name-parts) ;
        return [ sequence.join $(new-name-parts) ] ;
    }

    rule optional-properties ( )
    {
        return <name-modify>yes ;
    }
}
feature.feature name-modifier : : free ;
feature.feature name-modify : no yes : incidental optional ;
generators.register [ new name-modifier ] ;

# Translates <version> property to a set of modification properties
# that are applied by the name-modifier, and symlink-modifier.
#
rule version-to-modifier ( property : properties * )
{
    return
        <name-modify>yes
            <name-modifier><match>"^([^.]*)(.*)" <name-modifier><2>.$(property:G=)
            <name-modifier><symlink>yes
        ;
}
feature.action <version> : version-to-modifier ;
