/**
 *  Copyright (c) 2017 CentraleSupélec & EDF.
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License v1.0
 *  which accompanies this distribution, and is available at
 *  http://www.eclipse.org/legal/epl-v10.html
 *
 *  This file is part of the RiseClipse tool
 * 
 *  Contributors:
 *      Computer Science Department, CentraleSupélec
 *      EDF R&D
 *  Contacts:
 *      dominique.marcadet@centralesupelec.fr
 *      aurelie.dehouck-neveu@edf.fr
 *  Web site:
 *      http://wdi.supelec.fr/software/RiseClipse/
 */
import scl: 'http://www.iec.ch/61850/2003/SCL'

import 'BaseSimpleTypes.ocl'


package scl

context SclObject

-----------------------------------------------------------

def: validSclPredefinedPTypeEnum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        Set{
            'IP', 'IP-SUBNET', 'IP-GATEWAY', 'OSI-NSAP', 'OSI-TSEL', 'OSI-SSEL',
            'OSI-PSEL', 'OSI-AP-Title', 'OSI-AP-Invoke', 'OSI-AE-Qualifier',
            'OSI-AE-Invoke', 'MAC-Address', 'APPID', 'VLAN-PRIORITY', 'VLAN-ID',
            'SNTP-Port', 'MMS-Port', 'DNSName', 'IPv6FlowLabel', 'IPv6ClassOfTraffic',
            'C37-118-IP-Port', 'IP-UDP-PORT', 'IP-TCP-PORT', 'IPv6', 'IPv6-SUBNET',
            'IPv6-GATEWAY', 'IPv6-IGMPv3Src', 'IP-IGMPv3Src', 'IP-ClassOfTraffic'
        }->includes( s )
    else
        false
    endif

def: validSclExtensionPTypeEnum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        -- TODO: find the corresponding OCL RE
        --self.matches( '[A-Z][0-9A-Za-z\-]*' )
        -- according to the PDF restrictions it should be alphanumeric only
        s.matches( '[A-Z][0-9A-Za-z\u002D]*' )
    else
        false
    endif
 
def: validSclPTypeEnum( s : String ) : Boolean =
    if validSclPredefinedPTypeEnum( s ) then
        true
    else
        validSclExtensionPTypeEnum( s )
    endif

-----------------------------------------------------------

def: validSclPredefinedPTypePhysConnEnum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        Set{
            'Type', 'Plug', 'Cable', 'Port'
        }->includes( s )
    else
        false
    endif

def: validSclPTypePhysConnEnum( s : String ) : Boolean =
    if validSclPredefinedPTypePhysConnEnum( s ) then
        true
    else
        validSclExtensionPTypeEnum( s )
    endif
-----------------------------------------------------------

def: validSclPredefinedAttributeNameEnum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        Set{
            'T', 'Test', 'Check', 'SIUnit', 'Oper', 'SBO', 'SBOw', 'Cancel', 'Addr',
             'PRIORITY', 'VID', 'APPID', 'TransportInUse', 'IPClassOfTraffic', 'IPv6FlowLabel', 'IPAddressLength', 'IPAddress'
        }->includes( s )
    else
        false
    endif

def: validSclExtensionAttributeNameEnum( s : String ) : Boolean =
    if( self.validSclRestrName1stL( s ) ) then
        s.size() <= 60
    else
        false
    endif
 
def: validSclAttributeNameEnum( s : String ) : Boolean =
    if validSclPredefinedAttributeNameEnum( s ) then
        true
    else
        validSclExtensionAttributeNameEnum( s )
    endif
   
-----------------------------------------------------------

def: validSclPredefinedCommonConductingEquipmentEnum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        Set{
            'CBR', 'DIS', 'VTR', 'CTR', 'GEN', 'CAP', 'REA', 'CON', 'MOT', 'EFN',
            'PSH', 'BAT', 'BSH', 'CAB', 'GIL', 'LIN', 'RES', 'RRC', 'SAR', 'TCF',
            'TCR', 'IFL', 'FAN', 'SCR', 'SMC', 'PMP'
        }->includes( s )
    else
        false
    endif

def: validSclExtensionEquipmentEnum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        s.size() >= 3 and s.matches( 'E[A-Z]*' )
    else
        false
    endif
 
def: validSclCommonConductingEquipmentEnum( s : String ) : Boolean =
    if validSclPredefinedCommonConductingEquipmentEnum( s ) then
        true
    else
        validSclExtensionEquipmentEnum( s )
    endif

-----------------------------------------------------------

def: validSclPowerTransformerEnum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        Set{
            'PTR'
        }->includes( s )
    else
        false
    endif

-----------------------------------------------------------

def: validSclTransformerWindingEnum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        Set{
            'PTW'
        }->includes( s )
    else
        false
    endif

-----------------------------------------------------------

def: validSclPredefinedGeneralEquipmentEnum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        Set{
            'AXN', 'BAT', 'MOT', 'FAN', 'FIL', 'PMP', 'TNK', 'VLV'
        }->includes( s )
    else
        false
    endif

def: validSclExtensionGeneralEquipmentEnum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        s.size() >= 3 and s.matches( 'E[A-Z]*' )
    else
        false
    endif
 
def: validSclGeneralEquipmentEnum( s : String ) : Boolean =
    if validSclPredefinedGeneralEquipmentEnum( s ) then
        true
    else
        validSclExtensionGeneralEquipmentEnum( s )
    endif

-----------------------------------------------------------

-- This is a real enum
--def: validSclServiceSettingsNoDynEnum( s : String ) : Boolean =
--  if( self.validSclName( s ) ) then
--      Set{
--          'Conf', 'Fix'
--      }->includes( s )
--  else
--      false
--  endif

-----------------------------------------------------------

-- This is a real enum
--def: validSclServiceSettingsEnum( s : String ) : Boolean =
--  if( self.validSclName( s ) ) then
--      Set{
--          'Dyn', 'Conf', 'Fix'
--      }->includes( s )
--  else
--      false
--  endif

-----------------------------------------------------------

def: validSclRedProtEnum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        Set{
            'none', 'hsr', 'prp', 'rstp'
        }->includes( s )
    else
        false
    endif

-----------------------------------------------------------

-- This is a real enum
--def: validSclSMVDeliveryEnum( s : String ) : Boolean =
--  if( self.validSclName( s ) ) then
--      Set{
--          'unicast', 'multicast', 'both'
--      }->includes( s )
--  else
--      false
--  endif

-----------------------------------------------------------

-- This is a real enum
--def: validSclPhaseEnum( s : String ) : Boolean =
--  if( self.validSclName( s ) ) then
--      Set{
--          'A', 'B', 'C', 'N', 'all', 'none', 'AB', 'BC', 'CA'
--      }->includes( s )
--  else
--      false
--  endif

-----------------------------------------------------------

def: validSclAuthenticationEnum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        Set{
            'none', 'password', 'weak', 'strong', 'certificate'
        }->includes( s )
    else
        false
    endif

-----------------------------------------------------------

-- This is a real enum
--def: validSclAssociationKindEnum( s : String ) : Boolean =
--    if( self.validSclName( s ) ) then
--        Set{
--           'pre-established', 'predefined'
--        }->includes( s )
--    else
--        false
--    endif

-----------------------------------------------------------

def: validSclLPHDEnum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        Set{
            'LPHD'
        }->includes( s )
    else
        false
    endif
-----------------------------------------------------------

def: validSclLLN0Enum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        Set{
            'LLN0'
        }->includes( s )
    else
        false
    endif

-----------------------------------------------------------

def: validSclSystemLNGroupEnum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        Set{
            'LLN0', 'LPHD', 'LCCH', 'LGOS', 'LSVS', 'LTIM', 'LTMS', 'LTRK'
        }->includes( s )
    else
        false
    endif

def: validSclDomainLNGroupAEnum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        Set{
            'ANCR', 'ARCO', 'ARIS', 'ATCC', 'AVCO'
        }->includes( s )
    else
        false
    endif

def: validSclDomainLNGroupCEnum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        Set{
            'CALH', 'CCGR', 'CILO', 'CPOW', 'CSWI', 'CSYN'
        }->includes( s )
    else
        false
    endif

def: validSclDomainLNGroupFEnum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        Set{
            'FCNT', 'FCSD', 'FFIL', 'FLIM', 'FPID', 'FRMP', 'FSPT', 'FXOT', 'FXUT'
        }->includes( s )
    else
        false
    endif

def: validSclDomainLNGroupGEnum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        Set{
            'GAPC', 'GGIO', 'GLOG', 'GSAL'
        }->includes( s )
    else
        false
    endif

def: validSclDomainLNGroupIEnum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        Set{
            'IARC', 'IHMI', 'ISAF', 'ITCI', 'ITMI', 'ITPC'
        }->includes( s )
    else
        false
    endif

def: validSclDomainLNGroupKEnum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        Set{
            'KFAN', 'KFIL', 'KPMP', 'KTNK', 'KVLV'
        }->includes( s )
    else
        false
    endif

def: validSclDomainLNGroupMEnum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        Set{
            'MDIF', 'MENV', 'MFLK', 'MHAI', 'MHAN', 'MHYD', 'MMDC', 'MMET', 'MMTN',
            'MMTR', 'MMXN', 'MMXU', 'MSQI', 'MSTA'
        }->includes( s )
    else
        false
    endif

def: validSclDomainLNGroupPEnum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        Set{
            'PDIF', 'PDIR', 'PDIS', 'PDOP', 'PDUP', 'PFRC', 'PHAR', 'PHIZ', 'PIOC',
            'PMRI', 'PMSS', 'POPF', 'PPAM', 'PRTR', 'PSCH', 'PSDE', 'PTEF', 'PTHF',
            'PTOC', 'PTOF', 'PTOV', 'PTRC', 'PTTR', 'PTUC', 'PTUF', 'PTUV', 'PUPF',
            'PVOC', 'PVPH', 'PZSU'
        }->includes( s )
    else
        false
    endif

def: validSclDomainLNGroupQEnum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        Set{
            'QFVR', 'QITR', 'QIUB', 'QVTR', 'QVUB', 'QVVR'
        }->includes( s )
    else
        false
    endif

def: validSclDomainLNGroupREnum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        Set{
            'RADR', 'RBDR', 'RBRF', 'RDIR', 'RDRE', 'RDRS', 'RFLO', 'RMXU', 'RPSB', 'RREC', 'RSYN'
        }->includes( s )
    else
        false
    endif

def: validSclDomainLNGroupSEnum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        Set{
            'SARC', 'SCBR', 'SIMG', 'SIML', 'SLTC', 'SOPM', 'SPDC', 'SPTR', 'SSWI', 'STMP', 'SVBR'
        }->includes( s )
    else
        false
    endif

def: validSclDomainLNGroupTEnum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        Set{
            'TANG', 'TAXD', 'TCTR', 'TDST', 'TFLW', 'TFRQ', 'TGSN', 'THUM', 'TLVL',
            'TMGF', 'TMVM', 'TPOS', 'TPRS', 'TRTN', 'TSND', 'TTMP', 'TTNS', 'TVBR',
            'TVTR', 'TWPH'
        }->includes( s )
    else
        false
    endif

def: validSclDomainLNGroupXEnum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        Set{
            'XCBR', 'XSWI'
        }->includes( s )
    else
        false
    endif

def: validSclDomainLNGroupYEnum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        Set{
            'YEFN', 'YLTC', 'YPSH', 'YPTR'
        }->includes( s )
    else
        false
    endif

def: validSclDomainLNGroupZEnum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        Set{
            'ZAXN', 'ZBAT', 'ZBSH', 'ZCAB', 'ZCAP', 'ZCON', 'ZGEN', 'ZGIL', 'ZLIN',
            'ZMOT', 'ZREA', 'ZRES', 'ZRRC', 'ZSAR', 'ZSCR', 'ZSMC', 'ZTCF', 'ZTCR'
        }->includes( s )
    else
        false
    endif

def: validSclDomainLNEnum( s : String ) : Boolean =
       validSclDomainLNGroupAEnum( s )
    or validSclDomainLNGroupCEnum( s )
    or validSclDomainLNGroupFEnum( s )
    or validSclDomainLNGroupGEnum( s )
    or validSclDomainLNGroupIEnum( s )
    or validSclDomainLNGroupKEnum( s )
    or validSclDomainLNGroupMEnum( s )
    or validSclDomainLNGroupPEnum( s )
    or validSclDomainLNGroupQEnum( s )
    or validSclDomainLNGroupREnum( s )
    or validSclDomainLNGroupSEnum( s )
    or validSclDomainLNGroupTEnum( s )
    or validSclDomainLNGroupXEnum( s )
    or validSclDomainLNGroupYEnum( s )
    or validSclDomainLNGroupZEnum( s )

def: validSclPredefinedLNClassEnum( s : String ) : Boolean =
       validSclSystemLNGroupEnum( s )
    or validSclDomainLNEnum( s )

def: validSclExtensionLNClassEnum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        s.matches( '[A-Z]{4}' )
    else
        false
    endif
 
def: validSclLNClassEnum( s : String ) : Boolean =
    if validSclPredefinedLNClassEnum( s ) then
        true
    else
        validSclExtensionLNClassEnum( s )
    endif
   
-----------------------------------------------------------

def: validSclPredefinedCDCEnum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        Set{
            'SPS', 'DPS', 'INS', 'ENS', 'ACT', 'ACD', 'SEC', 'BCR', 'HST', 'VSS', 'MV',
            'CMV', 'SAV', 'WYE', 'DEL', 'SEQ', 'HMV', 'HWYE', 'HDEL', 'SPC', 'DPC', 'INC',
            'ENC', 'BSC', 'ISC', 'APC', 'BAC', 'SPG', 'ING', 'ENG', 'ORG', 'TSG', 'CUG',
            'VSG', 'ASG', 'CURVE', 'CSG', 'DPL', 'LPL', 'CSD', 'CST', 'BTS', 'UTS', 'LTS',
            'GTS', 'MTS', 'NTS', 'STS', 'CTS', 'OTS', 'VSD', 'ORS','TCS'
        }->includes( s )
    else
        false
    endif

def: validSclExtensionCDCEnum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        s.matches( '[A-Za-z]{1,5}' )
    else
        false
    endif
 
def: validSclCDCEnum( s : String ) : Boolean =
    if validSclPredefinedCDCEnum( s ) then
        true
    else
        validSclExtensionCDCEnum( s )
    endif
       
-----------------------------------------------------------

-- This is a real enum
--def: validSclFCEnum( s : String ) : Boolean =
--  if( self.validSclName( s ) ) then
--      Set{
--          'ST', 'MX', 'CO', 'SP', 'SG', 'SE', 'SV', 'CF', 'DC', 'EX', 'SR', 'BL', 'OR'
--      }->includes( s )
--  else
--      false
--  endif

-----------------------------------------------------------

def: validSclPredefinedBasicTypeEnum( s : String ) : Boolean =
    if( self.validSclName( s ) ) then
        Set{
            'BOOLEAN', 'INT8', 'INT16', 'INT24', 'INT32', 'INT64', 'INT128', 'INT8U',
            'INT16U', 'INT24U', 'INT32U', 'FLOAT32', 'FLOAT64', 'Enum', 'Dbpos', 'Tcmd',
            'Quality', 'Timestamp', 'VisString32', 'VisString64', 'VisString65',
            'VisString129', 'VisString255', 'Octet64', 'Unicode255', 'Struct', 'EntryTime',
            'Check', 'ObjRef', 'Currency', 'PhyComAddr', 'TrgOps', 'OptFlds', 'SvOptFlds',
            'EntryID', 'LogOptFlds', 'Octet6', 'Octet16'
        }->includes( s )
    else
        false
    endif

def: validSclBasicTypeEnum( s : String ) : Boolean =
    validSclPredefinedBasicTypeEnum( s )

-----------------------------------------------------------

-- This is a real enum
--def: validSclValKindEnum( s : String ) : Boolean =
--  if( self.validSclName( s ) ) then
--      Set{
--          'Spec', 'Conf', 'RO', 'Set'
--      }->includes( s )
--  else
--      false
--  endif

-----------------------------------------------------------

-- This is a real enum
--def: validSclGSEControlTypeEnum( s : String ) : Boolean =
--  if( self.validSclName( s ) ) then
--      Set{
--          'GSSE', 'GOOSE'
--      }->includes( s )
--  else
--      false
--  endif

-----------------------------------------------------------

-- This is a real enum
--def: validSclUnitMultiplierEnum( s : String ) : Boolean =
--  if( self.size( s ) = 0 ) then
--      true
--  else
--      Set{
--          'm', 'k', 'M', 'mu', 'y', 'z', 'a', 'f', 'p', 'n', 'c', 'd', 'da', 'h', 'G', 'T', 'P', 'E', 'Z', 'Y'
--      }->includes( s )
--  endif

-----------------------------------------------------------

def: validSclRightEnum( s : String ) : Boolean =
        Set{
            'full', 'fix', 'dataflow'
        }->includes( s )

-----------------------------------------------------------

def: validSclSDOCount( s : String ) : Boolean =
    s.matches( '[0-9]+' )
    or
    self.validSclRestrName1stL( s )

-----------------------------------------------------------

def: validSclDACount( s : String ) : Boolean =
    s.matches( '[0-9]+' )
    or
    self.validSclAttributeNameEnum( s )

-----------------------------------------------------------

-- This is a real enum
--def: validSclSmpMod( s : String ) : Boolean =
--      Set{
--          'SmpPerPeriod', 'SmpPerSec', 'SecPerSmp'
--      }->includes( s )

-----------------------------------------------------------

def: validSclPredefinedPhysConnTypeEnum( s : String ) : Boolean =
    Set{
        'Connection', 'RedConn'
    }->includes( s )

def: validSclExtensionPhysConnTypeEnum( s : String ) : Boolean =
   /* s.matches( '[A-Z][0-9A-Za-z]*' )
    * according to the PDF it should only contain alphanumeric characters*/
    s.matches( '[A-Z][0-9A-Za-z\u002D]*' )
 
def: validSclPhysConnTypeEnum( s : String ) : Boolean =
    if validSclPredefinedPhysConnTypeEnum( s ) then
        true
    else
        validSclExtensionPhysConnTypeEnum( s )
    endif
   
-----------------------------------------------------------

-- This is a real enum
--def: validSclServiceType( s : String ) : Boolean =
--  if( self.validSclName( s ) ) then
--      Set{
--          'Poll', 'Report', 'GOOSE', 'SMV'
--      }->includes( s )
--  else
--      false
--  endif

-----------------------------------------------------------

-- This is a real enum
--def: validSclPredefinedTypeOfSecurityEnum( s : String ) : Boolean =
--  Set{
--      'None', 'Signature', 'SignatureAndEncryption'
--  }->includes( s )

endpackage