# Copyright 2003 Dave Abrahams
# Copyright 2003, 2004, 2005, 2006 Vladimir Prus
# 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)

import "class" : new ;
import feature ;
import path ;
import project ;
import property ;
import sequence ;
import set ;
import option ;

# Class for storing a set of properties.
#
#   There is 1<->1 correspondence between identity and value. No two instances
# of the class are equal. To maintain this property, the 'property-set.create'
# rule should be used to create new instances. Instances are immutable.
#
#   Each property is classified with regard to its effect on build results.
# Incidental properties have no effect on build results, from Boost.Build's
# point of view. Others are either free, or non-free and we refer to non-free
# ones as 'base'. Each property belongs to exactly one of those categories.
#
#   It is possible to get a list of properties belonging to each category as
# well as a list of properties with a specific attribute.
#
#   Several operations, like and refine and as-path are provided. They all use
# caching whenever possible.
#
class property-set
{
    import errors ;
    import feature ;
    import path ;
    import property ;
    import property-set ;
    import set ;
    
    rule __init__ ( raw-properties * )
    {
        self.raw = $(raw-properties) ;

        for local p in $(raw-properties)
        {
            if ! $(p:G)
            {
                errors.error "Invalid property: '$(p)'" ;
            }

            local att = [ feature.attributes $(p:G) ] ;
            # A feature can be both incidental and free, in which case we add it
            # to incidental.
            if incidental in $(att)
            {
                self.incidental += $(p) ;
            }
            else if free in $(att)
            {
                self.free += $(p) ;
            }
            else
            {
                self.base += $(p) ;
            }

            if dependency in $(att)
            {
                self.dependency += $(p) ;
            }
            else
            {
                self.non-dependency += $(p) ;
            }

            if [ MATCH (:) : $(p:G=) ]
            {
                self.conditional += $(p) ;
            }
            else
            {
                self.non-conditional += $(p) ;
            }

            if propagated in $(att)
            {
                self.propagated += $(p) ;
            }
            if link-incompatible in $(att)
            {
                self.link-incompatible += $(p) ;
            }
        }
    }

    # Returns Jam list of stored properties.
    #
    rule raw ( )
    {
        return $(self.raw) ;
    }

    rule str ( )
    {
        return "[" $(self.raw) "]" ;
    }

    # Returns properties that are neither incidental nor free.
    #
    rule base ( )
    {
        return $(self.base) ;
    }

    # Returns free properties which are not incidental.
    #
    rule free ( )
    {
        return $(self.free) ;
    }

    # Returns dependency properties.
    #
    rule dependency ( )
    {
        return $(self.dependency) ;
    }

    rule non-dependency ( )
    {
        return $(self.non-dependency) ;
    }

    rule conditional ( )
    {
        return $(self.conditional) ;
    }

    rule non-conditional ( )
    {
        return $(self.non-conditional) ;
    }

    # Returns incidental properties.
    #
    rule incidental ( )
    {
        return $(self.incidental) ;
    }

    rule refine ( ps )
    {
        if ! $(self.refined.$(ps))
        {
            local r = [ property.refine $(self.raw) : [ $(ps).raw ] ] ;
            if $(r[1]) != "@error"
            {
                self.refined.$(ps) = [ property-set.create $(r) ] ;
            }
            else
            {
                self.refined.$(ps) = $(r) ;
            }
        }
        return $(self.refined.$(ps)) ;
    }

    rule expand ( )
    {
        if ! $(self.expanded)
        {
            self.expanded = [ property-set.create [ feature.expand $(self.raw) ] ] ;
        }
        return $(self.expanded) ;
    }

    rule expand-composites ( )
    {
        if ! $(self.composites)
        {
            self.composites = [ property-set.create
                [ feature.expand-composites $(self.raw) ] ] ;
        }
        return $(self.composites) ;
    }

    rule evaluate-conditionals ( context ? )
    {
        context ?= $(__name__) ;
        if ! $(self.evaluated.$(context))
        {
            self.evaluated.$(context) = [ property-set.create
                [ property.evaluate-conditionals-in-context $(self.raw) : [ $(context).raw ] ] ] ;
        }
        return $(self.evaluated.$(context)) ;
    }

    rule propagated ( )
    {
        if ! $(self.propagated-ps)
        {
            self.propagated-ps = [ property-set.create $(self.propagated) ] ;
        }
        return $(self.propagated-ps) ;
    }

    rule link-incompatible ( )
    {
        if ! $(self.link-incompatible-ps)
        {
            self.link-incompatible-ps =
              [ property-set.create $(self.link-incompatible) ] ;
        }
        return $(self.link-incompatible-ps) ;
    }

    rule run-actions ( )
    {
        if ! $(self.run)
        {
            self.run = [ property-set.create [ feature.run-actions $(self.raw) ] ] ;
        }
        return $(self.run) ;
    }

    rule add-defaults ( )
    {
        if ! $(self.defaults)
        {
            self.defaults = [ property-set.create
                [ feature.add-defaults $(self.raw) ] ] ;
        }
        return $(self.defaults) ;
    }

    rule as-path ( )
    {
        if ! $(self.as-path)
        {
            self.as-path = [ property.as-path $(self.base) ] ;
        }
        return $(self.as-path) ;
    }

    # Computes the path to be used for a target with the given properties.
    # Returns a list of
    #   - the computed path
    #   - if the path is relative to the build directory, a value of 'true'.
    #
    rule target-path ( )
    {
        if ! $(self.target-path)
        {
            # The <location> feature can be used to explicitly change the
            # location of generated targets.
            local l = [ get <location> ] ;
            if $(l)
            {
                self.target-path = $(l) ;
            }
            else
            {
                local p = [ as-path ] ;
                p = [ property-set.hash-maybe $(p) ] ;
                
                # A real ugly hack. Boost regression test system requires
                # specific target paths, and it seems that changing it to handle
                # other directory layout is really hard. For that reason, we
                # teach V2 to do the things regression system requires. The
                # value of '<location-prefix>' is prepended to the path.
                local prefix = [ get <location-prefix> ] ;
                if $(prefix)
                {
                    self.target-path = [ path.join $(prefix) $(p) ] ;
                }
                else
                {
                    self.target-path = $(p) ;
                }
                if ! $(self.target-path)
                {
                    self.target-path = . ;
                }
                # The path is relative to build dir.
                self.target-path += true ;
            }
        }
        return $(self.target-path) ;
    }

    rule add ( ps )
    {
        if ! $(self.added.$(ps))
        {
            self.added.$(ps) = [ property-set.create $(self.raw) [ $(ps).raw ] ] ;
        }
        return $(self.added.$(ps)) ;
    }

    rule add-raw ( properties * )
    {
        return [ add [ property-set.create $(properties) ] ] ;
    }

    rule link-incompatible-with ( ps )
    {
        if ! $(.li.$(ps))
        {
            local li1 = [ $(__name__).link-incompatible ] ;
            local li2 = [ $(ps).link-incompatible ] ;
            if [ set.equal $(li1) : $(li2) ]
            {
                .li.$(ps) = false ;
            }
            else
            {
                .li.$(ps) = true ;
            }
        }
        if $(.li.$(ps)) = true
        {
            return true ;
        }
        else
        {
            return ;
        }
    }

    # Returns all values of 'feature'.
    #
    rule get ( feature )
    {
        if ! $(self.map-built)
        {
            # For each feature, create a member var and assign all values to it.
            # Since all regular member vars start with 'self', there will be no
            # conflicts between names.
            self.map-built = true ;
            for local v in $(self.raw)
            {
                $(v:G) += $(v:G=) ;
            }
        }
        return $($(feature)) ;
    }
}


# Creates a new 'property-set' instance for the given raw properties or returns
# an already existing ones.
#
rule create ( raw-properties * )
{
    raw-properties = [ sequence.unique
        [ sequence.insertion-sort $(raw-properties) ] ] ;

    local key = $(raw-properties:J=-:E=) ;

    if ! $(.ps.$(key))
    {
        .ps.$(key) = [ new property-set $(raw-properties) ] ;
    }
    return $(.ps.$(key)) ;
}
NATIVE_RULE property-set : create ;


# Creates a new 'property-set' instance after checking that all properties are
# valid and converting incidental properties into gristed form.
#
rule create-with-validation ( raw-properties * )
{
    property.validate $(raw-properties) ;
    return [ create [ property.make $(raw-properties) ] ] ;
}


# Creates a property-set from the input given by the user, in the context of
# 'jamfile-module' at 'location'.
#
rule create-from-user-input ( raw-properties * : jamfile-module location )
{
    local specification = [ property.translate-paths $(raw-properties)
        : $(location) ] ;
    specification = [ property.translate-indirect $(specification)
        : $(jamfile-module) ] ;
    local project-id = [ project.attribute $(jamfile-module) id ] ;
    project-id ?= [ path.root $(location) [ path.pwd ] ] ;
    specification = [ property.translate-dependencies
                      $(specification) : $(project-id) : $(location) ] ;
    specification =
        [ property.expand-subfeatures-in-conditions $(specification) ] ;
    specification = [ property.make $(specification) ] ;
    return [ property-set.create $(specification) ] ;
}


# Refines requirements with requirements provided by the user. Specially handles
# "-<property>value" syntax in specification to remove given requirements.
# - parent-requirements -- property-set object with requirements to refine.
# - specification       -- string list of requirements provided by the user.
# - project-module      -- module to which context indirect features will be
#                          bound.
# - location            -- path to which path features are relative.
#
rule refine-from-user-input ( parent-requirements : specification * :
    project-module : location )
{
    if ! $(specification)
    {
        return $(parent-requirements) ;
    }
    else
    {
        local add-requirements ;
        local remove-requirements ;

        for local r in $(specification)
        {
            local m = [ MATCH "^-(.*)" : $(r) ] ;
            if $(m)
            {
                remove-requirements += $(m) ;
            }
            else
            {
                add-requirements += $(r) ;
            }
        }

        if $(remove-requirements)
        {
            # Need to create a property set, so that path features and indirect
            # features are translated just like they are in project
            # requirements.
            local ps = [ property-set.create-from-user-input
                $(remove-requirements) : $(project-module) $(location) ] ;

            parent-requirements = [ property-set.create
                [ set.difference [ $(parent-requirements).raw ]
                : [ $(ps).raw ] ] ] ;
            specification = $(add-requirements) ;
        }

        local requirements = [ property-set.create-from-user-input
            $(specification) : $(project-module) $(location) ] ;

        return [ $(parent-requirements).refine $(requirements) ] ;
    }
}


# Returns a property-set with an empty set of properties.
#
rule empty ( )
{
    if ! $(.empty)
    {
        .empty = [ create ] ;
    }
    return $(.empty) ;
}

if [ option.get hash : : yes ] = yes
{    
    rule hash-maybe ( path ? )
    {
        path ?= "" ;
        return [ MD5 $(path) ] ;
    }
}
else
{
    rule hash-maybe ( path ? )
    {
        return $(path) ;
    }    
}

