/**
 * Copyright 2017 - 2019  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 { AsyncSubject , Observable , of as observableOf } from 'rxjs' ; import { Injectable } from '@angular/core' ; import { Constraint } from '../../models/constraint-models/constraint' ; import { Pedigree } from '../../models/constraint-models/pedigree' ; import { SubjectSet } from '../../models/constraint-models/subject-set' ; import { TransmartTableState } from '../../models/transmart-models/transmart-table-state' ; import { TransmartDataTable } from '../../models/transmart-models/transmart-data-table' ; import { TransmartStudyDimensionElement } from 'app/models/transmart-models/transmart-study-dimension-element' ; import { AppConfig } from '../../config/app.config' ; import { TransmartExportElement } from '../../models/transmart-models/transmart-export-element' ; import { TransmartCrossTable } from '../../models/transmart-models/transmart-cross-table' ; import { TransmartConstraintMapper } from '../../utilities/transmart-utilities/transmart-constraint-mapper' ; import { ErrorHelper } from '../../utilities/error-helper' ; import { TransmartCountItem } from '../../models/transmart-models/transmart-count-item' ; import { TransmartStudy } from '../../models/transmart-models/transmart-study' ; import { catchError , map } from 'rxjs/operators' ; import { TransmartTrialVisit } from '../../models/transmart-models/transmart-trial-visit' ; import { HttpHelper } from '../../utilities/http-helper' ; import { HttpClient , HttpErrorResponse } from '@angular/common/http' ; import { TransmartExportJob } from '../../models/transmart-models/transmart-export-job' ; import { TransmartPatient } from '../../models/transmart-models/transmart-patient' ; import { TransmartDimension } from '../../models/transmart-models/transmart-dimension' ; @ Injectable ( { providedIn : 'root' , } ) export class TransmartHttpService { static sortableDimensions = new Set < string > ( [ 'patient' , 'concept' , 'start time' , 'end time' , 'visit' , 'location' , 'provider' , 'study' , 'trial visit' ] ) ; private httpHelper : HttpHelper ; private _endpointUrl : string ; private _studiesLock : boolean ; private _studies : TransmartStudy [ ] = null ; private _studiesSubject : AsyncSubject < TransmartStudy [ ] > ; constructor ( private appConfig , private httpClient ) { if ( this . appConfig . isLoaded ) { this . endpointUrl = `${ this . appConfig . getConfig ( 'api-url' ) }/${ this . appConfig . getConfig ( 'api-version' ) }` ; this . httpHelper = new HttpHelper ( this . endpointUrl , httpClient ) ; } } get endpointUrl ( ) : string { return this . _endpointUrl ; } set endpointUrl ( value ) { this . _endpointUrl = value ; } getStatus ( ) { return Observable . from ( new Promise < string > ( ( resolve , reject ) => this . httpClient . get ( `${ this . appConfig . getConfig ( 'api-url' ) }/health` ) . subscribe ( response => { resolve ( response [ 'status' ] ) ; } , error => { if ( error [ 'status' ] === 503 ) { resolve ( error [ 'error' ] [ 'status' ] ) ; } else { console . error ( 'Error response' , error ) ; reject ( error ) ; } } ) ) ) ; } returns { Observable < Study [ ] > } getStudies ( ) { const urlPart = 'studies' ; const responseField = 'studies' ; return this . httpHelper . getCall ( urlPart , responseField ) ; } return { Promise < Study [ ] > } get studies ( ) : Promise < TransmartStudy [ ] > { if ( this . _studies != null ) { return observableOf ( this . _studies ) . toPromise ( ) ; } if ( this . _studiesLock ) { return this . _studiesSubject . toPromise ( ) ; } this . _studiesLock = true ; this . _studiesSubject = new AsyncSubject < TransmartStudy [ ] > ( ) ; return new Promise ( ( resolve , reject ) => { this . getStudies ( ) . subscribe ( ( studies ) => { resolve ( studies ) ; this . _studies = studies ; this . _studiesSubject . next ( this . _studies ) ; this . _studiesSubject . complete ( ) ; this . _studiesLock = false ; } , ( error ) => { console . error ( `Error retrieving studies: ${ error }` ) ; reject ( error ) ; this . _studies = [ ] ; this . _studiesSubject . next ( this . _studies ) ; this . _studiesSubject . complete ( ) ; this . _studiesLock = false ; } ) ; } ) ; } param { string } root param { number } depth param { boolean } hasCounts param { boolean } hasTags returns { Observable < Object > } getTreeNodes ( root , depth , hasCounts , hasTags ) { let urlPart = `tree_nodes?root=${ encodeURIComponent ( root ) }&depth=${ depth }` ; if ( hasCounts ) { urlPart += '&counts=true' ; } if ( hasTags ) { urlPart += '&tags=true' ; } const responseField = 'tree_nodes' ; return this . httpHelper . getCall ( urlPart , responseField ) ; } param { Constraint } constraint returns { Observable < Object > } getCountsPerStudyAndConcept ( constraint ) { const urlPart = 'observations/counts_per_study_and_concept' ; const body = { constraint : TransmartConstraintMapper . mapConstraint ( constraint ) } ; const responseField = 'countsPerStudy' ; return this . httpHelper . postCall ( urlPart , body , responseField ) ; } param { Constraint } constraint returns { Observable < Object > } getCountsPerStudy ( constraint ) { const urlPart = 'observations/counts_per_study' ; const body = { constraint : TransmartConstraintMapper . mapConstraint ( constraint ) } ; const responseField = 'countsPerStudy' ; return this . httpHelper . postCall ( urlPart , body , responseField ) ; } param { Constraint } constraint returns { Observable < any > } getCountsPerConcept ( constraint ) { const urlPart = 'observations/counts_per_concept' ; const body = { constraint : TransmartConstraintMapper . mapConstraint ( constraint ) } ; const responseField = 'countsPerConcept' ; return this . httpHelper . postCall ( urlPart , body , responseField ) ; } param { Constraint } constraint returns { Observable < Object > } getCounts ( constraint ) { const urlPart = 'observations/counts' ; const body = { constraint : TransmartConstraintMapper . mapConstraint ( constraint ) } ; const responseField = false ; return this . httpHelper . postCall ( urlPart , body , responseField ) ; } param { Constraint } constraint returns { Observable < object > } getAggregate ( constraint ) { const urlPart = 'observations/aggregates_per_concept' ; const body = { constraint : TransmartConstraintMapper . mapConstraint ( constraint ) } ; const responseField = 'aggregatesPerConcept' ; return this . httpHelper . postCall ( urlPart , body , responseField ) ; } getCategoricalAggregate ( constraint ) { const urlPart = 'observations/aggregates_per_categorical_concept' ; const body = { constraint : TransmartConstraintMapper . mapConstraint ( constraint ) } ; const responseField = 'aggregatesPerCategoricalConcept' ; return this . httpHelper . postCall ( urlPart , body , responseField ) ; } param constraint returns { Observable < R | T > } getTrialVisits ( constraint ) { const urlPart = `dimensions/trial visit/elements` ; const body = { constraint : TransmartConstraintMapper . mapConstraint ( constraint ) } ; const responseField = 'elements' ; return this . httpHelper . postCall ( urlPart , body , responseField ) ; } returns { Observable < Pedigree [ ] > } getPedigrees ( ) { const urlPart = 'pedigree/relation_types' ; const responseField = 'relationTypes' ; return this . httpHelper . getCall ( urlPart , responseField ) ; } param constraint returns { Observable < TransmartPatient [ ] > } getPatients ( constraint ) { const urlPart = 'patients' ; const body = { constraint : TransmartConstraintMapper . mapConstraint ( constraint ) } ; const responseField = 'patients' ; return this . httpHelper . postCall ( urlPart , body , responseField ) ; } param constraint returns { Observable < string [ ] > } getExportDataFormats ( constraint ) { const urlPart = 'export/data_formats' ; const body = { constraint : TransmartConstraintMapper . mapConstraint ( constraint ) } ; const responseField = 'dataFormats' ; return this . httpHelper . postCall ( urlPart , body , responseField ) ; } getExportFileFormats ( dataView ) { const urlPart = `export/file_formats?dataView=${ dataView }` ; const responseField = 'fileFormats' ; return this . httpHelper . getCall ( urlPart , responseField ) ; } returns { Observable < TransmartExportJob [ ] > } getExportJobs ( ) { const urlPart = 'export/jobs' ; const responseField = 'exportJobs' ; return this . httpHelper . getCall ( urlPart , responseField ) ; } param name returns { Observable < TransmartExportJob > } createExportJob ( name ) { const urlPart = `export/job?name=${ encodeURIComponent ( name ) }` ; const responseField = 'exportJob' ; return this . httpHelper . postCall ( urlPart , { } , responseField ) ; } param { string } jobId param { Constraint } targetConstraint param { TransmartExportElement [ ] } elements param { TransmartTableState } tableState returns { Observable < TransmartExportJob > } runExportJob ( jobId , targetConstraint , elements , tableState ? ) { const urlPart = `export/${ jobId }/run` ; const responseField = 'exportJob' ; let body = { constraint : TransmartConstraintMapper . mapConstraint ( targetConstraint ) , elements : elements } ; if ( tableState ) { body [ 'tableConfig' ] = tableState ; } return this . httpHelper . postCall ( urlPart , body , responseField ) ; } param jobId param targetConstraint param elements param dateColumnsIncluded returns { Observable < TransmartExportJob > } runSurveyTableExportJob ( jobId , targetConstraint , elements , dateColumnsIncluded ) { const urlPart = `export/${ jobId }/run` ; const responseField = 'exportJob' ; let body = { constraint : TransmartConstraintMapper . mapConstraint ( targetConstraint ) , elements : elements , includeMeasurementDateColumns : dateColumnsIncluded } ; return this . httpHelper . postCall ( urlPart , body , responseField ) ; } param jobId returns { Observable < blob > } downloadExportJob ( jobId ) { let urlPart = `export/${ jobId }/download` ; return this . httpHelper . downloadData ( urlPart ) ; } param jobId returns { Observable < blob > } cancelExportJob ( jobId ) { const urlPart = `export/${ jobId }/cancel` ; const responseField = 'exportJob' ; return this . httpHelper . postCall ( urlPart , { } , responseField ) ; } param jobId returns { Observable < blob > } archiveExportJob ( jobId ) { const urlPart = `export/${ jobId }` ; return this . httpHelper . deleteCall ( urlPart ) ; } savePatientSet ( name , constraint ) { const urlPart = `patient_sets?name=${ name }&reuse=true` ; const body = TransmartConstraintMapper . mapConstraint ( constraint ) ; return this . httpHelper . postCall ( urlPart , body , null ) ; } getDataTable ( tableState , constraint , offset , limit ) { const urlPart = `observations/table` ; let body = { type : 'clinical' , constraint : TransmartConstraintMapper . mapConstraint ( constraint ) , rowDimensions : tableState . rowDimensions , columnDimensions : tableState . columnDimensions , offset : offset , limit : limit , rowSort : tableState . rowSort , columnSort : tableState . columnSort } ; return this . httpHelper . postCall ( urlPart , body , null ) ; } getStudyIds ( constraint ) { const urlPart = `dimensions/study/elements` ; const body = { constraint : TransmartConstraintMapper . mapConstraint ( constraint ) } ; const responseField = 'elements' ; return this . httpHelper . postCall ( urlPart , body , responseField ) . pipe ( map ( ( elements ) => elements . map ( element => element . name ) ) ) ; } getCrossTable ( baseConstraint , rowConstraints , columnConstraints ) { const urlPart = 'observations/crosstable' ; const body = { subjectConstraint : TransmartConstraintMapper . mapConstraint ( baseConstraint ) , rowConstraints : rowConstraints . map ( constraint => TransmartConstraintMapper . mapConstraint ( constraint ) ) , columnConstraints : columnConstraints . map ( constraint => TransmartConstraintMapper . mapConstraint ( constraint ) ) } ; return this . httpHelper . postCall ( urlPart , body , null ) ; } /**
     * Get a list of all dimensions supported by transmart.
     */ getDimensions ( ) { const urlPart = 'dimensions' ; const responseField = 'dimensions' ; return this . httpHelper . getCall ( urlPart , responseField ) ; } }