#
# Copyright 2014 ETH Zuerich, Scientific IT Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License 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.
#

# MasterDataRegistrationTransaction Class
import definitions
import definitionsVoc
import os
import copy
import ch.systemsx.cisd.openbis.generic.server.jython.api.v1.DataType as DataType

##
## Globals
##
vocabulariesCache = {};
propertiesCache = {};
samplesCache = {};
tr = service.transaction()

##
## API Facade
##
def createVocabularyWithTerms(vocabularyCode, terms):
    vocabulary = tr.getOrCreateNewVocabulary(vocabularyCode);
    vocabulary.setChosenFromList(True);
    addTerms(vocabulary, terms);
    vocabulariesCache[vocabularyCode] = vocabulary;
    
def addTerms(vocabulary, terms):
    for term in terms:
        addTermWithLabel(vocabulary, term[0], term[1])
    
def addTermWithLabel(vocabulary, termCode, termLabel):
    newTerm = tr.createNewVocabularyTerm(termCode);
    newTerm.setLabel(termLabel);
    vocabulary.addTerm(newTerm);
    
def createSampleTypeWithProperties(sampleTypeCode, description, properties):
    newSampleType = tr.getOrCreateNewSampleType(sampleTypeCode);
    newSampleType.setDescription(description);
    newSampleType.setShowParents(True);
    newSampleType.setAutoGeneratedCode(True);
    newSampleType.setGeneratedCodePrefix(sampleTypeCode[:3]);
    addProperties(newSampleType, properties);
    samplesCache[sampleTypeCode] = newSampleType;
    


def getSampleType(sampleTypeCode):
    sampleType = None
    if sampleTypeCode in samplesCache:
        sampleType = samplesCache[sampleTypeCode];
    else:
        sampleType = tr.getSampleType(sampleTypeCode)
        samplesCache[sampleTypeCode] = sampleType;
    return sampleType;
            
def addPropertiesToSamples(sampleTypeCodes, properties):
    for sampleTypeCode in sampleTypeCodes:
        sampleType = getSampleType(sampleTypeCode);
        addProperties(sampleType, properties);
    
def addProperties(entity, properties):
    for property in properties:
        if not property[0].startswith("*"):
            showInEditViews = None;
            if len(property) > 9 and property[9] is not None:
                showInEditViews = property[9];
            addProperty(entity, property[0], property[1], property[2], property[3], property[4], property[5], property[6], property[7], property[8], showInEditViews);
    
def addProperty(entity, propertyCode, section, propertyLabel, dataType, vocabularyCode, propertyDescription, managedScript, dynamicScript, isMandatory, showInEditViews):
    property = None;
    
    if propertyCode in propertiesCache:
        property = propertiesCache[propertyCode];
    else:
        property = createProperty(propertyCode, dataType, propertyLabel, propertyDescription, vocabularyCode);
    
    propertyAssignment = tr.assignPropertyType(entity, property); #If the assignment already exists, returns the existing one
    propertyAssignment.setSection(section);
    propertyAssignment.setShownEdit(True);
    propertyAssignment.setMandatory(isMandatory);
    
    if showInEditViews is not None:
        propertyAssignment.setShownEdit(showInEditViews);
    
    if managedScript != None:
        propertyAssignment.setManaged(True);
        propertyAssignment.setScriptName(managedScript);
    if dynamicScript != None:
        propertyAssignment.setDynamic(True);
        propertyAssignment.setShownEdit(False);
        propertyAssignment.setScriptName(dynamicScript);

def createProperty(propertyCode, dataType, propertyLabel, propertyDescription, vocabularyCode):
    property = tr.getOrCreateNewPropertyType(propertyCode, dataType);
    property.setDescription(propertyDescription);
    property.setLabel(propertyLabel);
    propertiesCache[propertyCode] = property;
    if dataType == DataType.CONTROLLEDVOCABULARY:
        property.setVocabulary(vocabulariesCache[vocabularyCode]);
    return property;

def findAssignment(entityType, propertyType):
    for assignment in tr.listPropertyAssignments():
        if assignment.getEntityKind().equals(entityType.getEntityKind()) and assignment.getEntityTypeCode() == entityType.getCode() and assignment.getPropertyTypeCode() == propertyType.getCode():
            return assignment;
    return None;
    
##
## Vocabulary Types
##
for vocabularyCode, vocabularyValues in definitionsVoc.vocabularyDefinitions.iteritems():
    createVocabularyWithTerms(vocabularyCode, vocabularyValues)

##
## Sample Types
##
createSampleTypeWithProperties("CELL_LINE", "", definitions.CELL_LINE);
createSampleTypeWithProperties("STORAGE_POSITION", "", definitions.STORAGE_POSITION);