#####################################################################
#####################################################################
## Copyright 2005 Steven R. Newcomb                                ##
##                                                                 ##
## This software is licensed under the Apache License, Version 2.0 ##
## (the "License"); you may not use this file except in compliance ##
## with the License.  Copies of the License are available at       ##
##        http://www.apache.org/licenses/LICENSE-2.0               ##
##                                                                 ##
## Unless required by applicable law or agreed to in writing,      ##
## software distributed under the License is distributed on an "AS ##
## IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either ##
## express or implied.  See the License for the specific language  ##
## governing permissions and limitations under the License.        ##
##                                                                 ##
## Copies of the source code and the license are available at      ##
##        http://www.versavant.org                                 ##
#####################################################################
#####################################################################

####################################
cvsRevision = "$Revision: 1.2 $" ##
####################################


#####################################################################
## Implementation of the conferral rules "inferFrom_a_sip_"
## in Topic Map Application "BIGASSERT".
#####################################################################


import sys, copy

def reifyRolesIn_A_assert_a_sips( vsv, conferralRule, **args):
    ## from bridgeFromTMAName,,a_sip properties, infer a_sip
    ## properties in the conferralRule's TMA.  (With all that that
    ## entails.)

    bridgeFromTMAName  = args[ 'bridgeFromTMAName']
    
    topicMap = conferralRule.topicMap  ## make the below code less verbose (and maybe run slightly faster)
    TMA = conferralRule.TMA  ## this is the TMA that defines this conferral rule
    bridgeFromTMA = topicMap.TMAs[ bridgeFromTMAName]
    bridgeFrom_a_sip_overheadDict = bridgeFromTMA.propertyClasses[ 'a_sip'].overheadDict

    old_a_sip_hashableValueList = bridgeFrom_a_sip_overheadDict.keys()

    for old_a_sip_hashableValue in old_a_sip_hashableValueList:

        old_a_proxyIdList = copy.copy( bridgeFrom_a_sip_overheadDict[ old_a_sip_hashableValue])

        for old_a_proxyId in old_a_proxyIdList:

            old_a_proxy = topicMap.proxies[ old_a_proxyId]
            old_a_sip_instance = old_a_proxy.propertyInstances[ vsv.catKey( bridgeFromTMA.TMAName, 'a_sip')]

            ## Don't be triggered by an a_sip_instance property more
            ## than once, and don't be triggered by any a_sip_instance
            ## that was output by an operation of this rule
            conferralRuleTriggerRoleId = vsv.catKey( conferralRule.conferralRuleKey, 'a_sip value')
            if old_a_sip_instance.conferralTriggerAncestry.has_key( conferralRuleTriggerRoleId) or \
                   old_a_sip_instance.conferralsTriggered.has_key( conferralRuleTriggerRoleId):
                continue

            triggers = {}  ## new dictionary to work in
            triggers[ 'a_sip value'] = old_a_sip_instance.propertyInstanceKey
            conferredValueSources = {}  ## new dictionary to work in
            conferredValueSources[ 'a_sip value'] = old_a_sip_instance.propertyInstanceKey

            if vsv.conferralMayBeSignificant( conferralRule, triggers, conferredValueSources):

                    ## Here we need to convert each r-proxy reference
                    ## (the first member of each tuple) into a string
                    ## which will serve as the role name.

                    roleNames = {}
                    for thisTuple in old_a_sip_instance._value:

                        new_r_proxy = vsv.newProxyObject()

                        roleName = thisTuple[ 0]
                        vsv.newPropertyInstance( new_r_proxy,
                            TMA.TMAName,
                            'role name',
                            vsv.versaCopy( roleName),
                            triggers,
                            conferredValueSources)         

                        if roleName in roleNames:
                            vsv.errMsg( '%s value cannot be bridged to %s: two or more roleNames turn out to be "%s".' % ( old_a_sip_instance.propertyInstanceKey, vsv.catKey( TMA.TMAName, 'role name'), roleName))
                            sys.exit( 1)
                        roleNames[ roleName] = None

#######################################################
def reifyRolesIn_U_assert_properties( vsv, conferralRule, **args):
    ## from bridgeFromTMAName,,x_LrnRrnRrp properties, infer a_sip
    ## properties in the conferralRule's TMA.  (With all that that
    ## entails.)

    u_assertTMAName = args[ 'bridgeFromTMAName']
    u_assertPropertyName = 'x_LrnRrnRrp'

    topicMap = conferralRule.topicMap
    TMA = conferralRule.TMA  ## this is the TMA that defines this conferral rule
    u_assertTMA = topicMap.TMAs[ u_assertTMAName]
    proxyIdList = u_assertTMA.propertyClasses[ u_assertPropertyName].overheadDict[ 'proxyIds'].keys()
    u_assertPropertyInstanceInProxyKey = vsv.catKey( u_assertTMAName, u_assertPropertyName)

    existingRoleDict = TMA.propertyClasses[ 'role name'].overheadDict

    for proxyId in proxyIdList:

        proxy = topicMap.proxies[ proxyId]

        u_assertProperty = proxy.propertyInstances[ u_assertPropertyInstanceInProxyKey]

        ## Don't be triggered by a u_assert property more than once
        conferralRuleTriggerRoleId = vsv.catKey( conferralRule.conferralRuleKey, 'A')
        if u_assertProperty.conferralTriggerAncestry.has_key( conferralRuleTriggerRoleId) or \
               u_assertProperty.conferralsTriggered.has_key( conferralRuleTriggerRoleId):
            continue

        triggers = {}  ## new dictionary to work in
        triggers[ 'A'] = u_assertProperty.propertyInstanceKey
        conferredValueSources = {}  ## new dictionary to work in
        conferredValueSources[ 'A'] = u_assertProperty.propertyInstanceKey

        if vsv.conferralMayBeSignificant( conferralRule, triggers, conferredValueSources):

            dict1 = u_assertProperty._value

            for dict1Key in dict1:
                localRoleName = dict1Key
                if localRoleName not in existingRoleDict:
                    newProxy = vsv.newProxyObject( topicMap)
                    vsv.newPropertyInstance( newProxy,
                                             TMA,
                                             'role name',
                                             vsv.versaCopy( localRoleName),
                                             triggers,
                                             conferredValueSources)

                dict2 = dict1[ dict1Key]
                for dict2Key in dict2:
                    remoteRoleName = dict2Key
                    if remoteRoleName not in existingRoleDict:
                        newProxy = vsv.newProxyObject( topicMap)
                        vsv.newPropertyInstance( newProxy,
                                                 TMA,
                                                 'role name',
                                                 vsv.versaCopy( remoteRoleName),
                                                 triggers,
                                                 conferredValueSources)

