/**
 * Copyright 2017 - 2018  The Hyve B.V.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */ import { ConceptConstraint } from '../../models/constraint-models/concept-constraint' ; import { ConceptType } from '../../models/constraint-models/concept-type' ; import { Constraint } from '../../models/constraint-models/constraint' ; import { CombinationConstraint } from '../../models/constraint-models/combination-constraint' ; import { CombinationState } from '../../models/constraint-models/combination-state' ; import { TrueConstraint } from '../../models/constraint-models/true-constraint' ; export class ConstraintHelper { param { Constraint } constraint return { boolean } static isCategoricalConceptConstraint ( constraint ) { if ( constraint . className !== 'ConceptConstraint' ) { return false ; } let conceptConstraint = < ConceptConstraint > constraint ; return conceptConstraint . concept . type === ConceptType . CATEGORICAL ; } param { Constraint [ ] [ ] } constraints return { Constraint [ ] [ ] } static permuteConstraints ( constraints ) { if ( constraints . length < 1 ) { return [ [ ] ] ; } let head = constraints . shift ( ) ; let tailPermutations = this . permuteConstraints ( constraints ) ; let result = [ ] ; head . forEach ( ( constraint ) => { tailPermutations . forEach ( ( permutation ) => { result . push ( [ constraint ] . concat ( permutation ) ) ; } ) ; } ) ; return result ; } param { Constraint [ ] } constraints return { Constraint } static combineSubjectLevelConstraints ( constraints ) { if ( constraints . length < 1 ) { return new TrueConstraint ( ) ; } else if ( constraints . length === 1 ) { return constraints [ 0 ] ; } else { let combination = new CombinationConstraint ( ) ; combination . combinationState = CombinationState . And ; constraints . forEach ( child => combination . addChild ( child ) ) ; return combination ; } } param { Constraint } observationConstraint return { Constraint } static ensurePatientLevelConstraint ( observationConstraint ) { if ( observationConstraint . className === 'CombinationConstraint' && ( < CombinationConstraint > observationConstraint ) . dimension !== 'patient' || observationConstraint . className !== 'CombinationConstraint' ) { return new CombinationConstraint ( [ observationConstraint ] , CombinationState . And , 'patient' ) ; } return observationConstraint ; } param { Constraint } constraint return { boolean } static isConjunctiveAndHasOneCategoricalConstraint ( constraint ) { if ( constraint . className === 'CombinationConstraint' ) { let combiConstraint = < CombinationConstraint > constraint ; if ( combiConstraint . isAnd ( ) ) { let categoricalConceptConstraints = combiConstraint . children . filter ( ( child ) => ConstraintHelper . isCategoricalConceptConstraint ( child ) ) ; return categoricalConceptConstraints . length === 1 ; } } return false ; } param { CombinationConstraint } combination return { boolean } static hasNonEmptyChildren ( combination ) { return combination . children . some ( ( child ) => { if ( child . className === 'CombinationConstraint' && ( < CombinationConstraint > child ) . dimension === combination . dimension && child . negated === false ) { return this . hasNonEmptyChildren ( < CombinationConstraint > child ) ; } return true ; } ) ; } /**
     * Return a brief string representation of a constraint.
     * Note that not all constraint types are supported.
     */ static brief ( constraint ) { if ( constraint . className === 'CombinationConstraint' ) { let combiConstraint = < CombinationConstraint > constraint ; if ( combiConstraint . isAnd ( ) ) { let categoricalConceptConstraints = combiConstraint . children . filter ( ( child ) => ConstraintHelper . isCategoricalConceptConstraint ( child ) ) ; if ( categoricalConceptConstraints . length === 1 ) { return ( < ConceptConstraint > categoricalConceptConstraints [ 0 ] ) . concept . name ; } } } else if ( ConstraintHelper . isCategoricalConceptConstraint ( constraint ) ) { return ( < ConceptConstraint > constraint ) . concept . name ; } return constraint . textRepresentation ; } }