001package org.hl7.fhir.r5.renderers.spreadsheets;
002
003import java.io.IOException;
004import java.util.List;
005
006import lombok.extern.slf4j.Slf4j;
007import org.apache.poi.ss.usermodel.Sheet;
008import org.hl7.fhir.r5.context.IWorkerContext;
009import org.hl7.fhir.r5.model.CanonicalType;
010import org.hl7.fhir.r5.model.ValueSet;
011import org.hl7.fhir.r5.model.ValueSet.ConceptReferenceComponent;
012import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
013import org.hl7.fhir.r5.model.ValueSet.ConceptSetFilterComponent;
014import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
015import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionParameterComponent;
016import org.hl7.fhir.utilities.MarkedToMoveToAdjunctPackage;
017
018@MarkedToMoveToAdjunctPackage
019@Slf4j
020public class ValueSetSpreadsheetGenerator extends CanonicalSpreadsheetGenerator {
021
022  public ValueSetSpreadsheetGenerator(IWorkerContext context) {
023    super(context);
024  }
025
026  public boolean canGenerate(ValueSet vs) {
027    return true;
028  }
029
030  public ValueSetSpreadsheetGenerator renderValueSet(ValueSet vs) throws IOException {
031    if (vs == null) {
032      log.warn("no valueset!");
033    }
034    addValueSetMetadata(renderCanonicalResource(vs, false), vs);
035    int i = 0;
036    for (ConceptSetComponent inc : vs.getCompose().getInclude()) {
037      genInclude(vs, inc, "Include", i++);
038    }
039    for (ConceptSetComponent exc : vs.getCompose().getExclude()) {
040      genInclude(vs, exc, "Exclude", i++);
041    }   
042    if (vs.hasExpansion()) {
043      if (vs.getExpansion().hasParameter()) {
044        genExpansionParams(vs.getExpansion().getParameter());        
045      }
046      genExpansion(vs.getExpansion().getContains());
047    }
048    return this;
049  }
050
051  private void addValueSetMetadata(Sheet sheet, ValueSet vs) {
052    addMetadataRow(sheet, "Immutable", vs.getImmutableElement().toString());
053  }
054
055  private void genExpansionParams(List<ValueSetExpansionParameterComponent> params) {
056    Sheet sheet = makeSheet("Expansion Parameters");
057    addHeaders(sheet, "Parameter", "Value");
058    for (ValueSetExpansionParameterComponent p : params) {
059      addRow(sheet, p.getName(), dr.displayDataType(p.getValue()));          
060    }    
061  }
062
063  private void genExpansion(List<ValueSetExpansionContainsComponent> list) {
064    Sheet sheet = makeSheet("Expansion");
065    addHeaders(sheet, "Level", "System", "version", "Code", "Display", "Abstract", "Inactive");
066    genExpansionEntry(1, list, sheet);    
067  }
068
069  public void genExpansionEntry(int level, List<ValueSetExpansionContainsComponent> list, Sheet sheet) {
070    for (ValueSetExpansionContainsComponent p : list) {
071      addRow(sheet, Integer.toString(level), p.getSystem(), p.getVersion(), p.getCode(), p.getDisplay(), bool(p.getAbstract()), bool(p.getInactive()));  
072      if (p.hasContains()) {
073        genExpansionEntry(level + 1, p.getContains(), sheet);
074      }
075    }
076  }
077  
078  private String bool(boolean value) {    
079    return value ? "" : "false";
080  }
081
082  private void genInclude(ValueSet vs, ConceptSetComponent inc, String mode, int count) {
083    if (inc.hasSystem()) {
084      genIncludeSystem(vs, inc, mode, count);
085    } else {
086      genIncludeValueSets(vs, inc, mode, count);      
087    }
088//    String subname = inc.hasSystem() ?  : "ValueSets";
089//    
090//
091//  Row headerRow = sheet.createRow(0);
092//  for (int i = 0; i < titles.length; i++) {
093//    addCell(headerRow, i, titles[i], styles.get("header"));
094//  }
095//  int i = titles.length - 1;
096//  for (StructureDefinitionMappingComponent map : sd.getMapping()) {
097//    i++;
098//    addCell(headerRow, i, "Mapping: " + map.getName(), styles.get("header"));
099//  }    
100//
101//  for (ElementDefinition child : sd.getSnapshot().getElement()) {
102//    processElement(sheet, sd, child);
103//  }
104//  configureSheet(sheet, sd);
105  }
106
107  private void genIncludeValueSets(ValueSet vs, ConceptSetComponent inc, String mode, int count) {
108    Sheet sheet = makeSheet(mode+" ValueSet #"+count);
109    addValueSets(sheet, inc.getValueSet()); 
110    configureSheet(sheet);
111  }
112
113  private void genIncludeSystem(ValueSet vs, ConceptSetComponent inc, String mode, int count) {
114    Sheet sheet = makeSheet(mode+" #"+count);
115    if (inc.hasValueSet()) {
116      addValueSets(sheet, inc.getValueSet());
117    }
118    if (inc.hasFilter()) {
119      addFilters(sheet, inc.getFilter());
120    }
121    if (inc.hasConcept()) {
122      addConcepts(sheet, inc.getConcept());
123    }
124    if (!inc.hasConcept() && !inc.hasFilter()) {
125      addAllCodes(sheet);
126    }
127    addRow(sheet, "", "");          
128    addRow(sheet, "System URI", inc.getSystem());          
129    
130    configureSheet(sheet);
131  }
132
133  private void addAllCodes(Sheet sheet) {
134    addHeaders(sheet, "Codes");     
135    addRow(sheet, "All codes");          
136  }
137
138  private void addValueSets(Sheet sheet, List<CanonicalType> valueSets) {
139    addHeaders(sheet, "ValueSet URL");
140    for (CanonicalType u : valueSets) {
141      addRow(sheet, u.getValue());
142    }
143  }
144
145  private void configureSheet(Sheet sheet) {
146    sheet.setColumnWidth(0, columnPixels(30));
147    sheet.setColumnWidth(1, columnPixels(40));
148    sheet.setColumnWidth(1, columnPixels(50));
149  }
150
151  private void addConcepts(Sheet sheet, List<ConceptReferenceComponent> concepts) {
152    addHeaders(sheet, "Concept", "Description"); // todo: designations    
153    for (ConceptReferenceComponent cd : concepts) {
154      addRow(sheet, cd.getCode(), cd.getDisplay());      
155    }    
156  }
157
158  private void addFilters(Sheet sheet, List<ConceptSetFilterComponent> filters) {
159    addHeaders(sheet, "Property", "Operation", "Value");    
160    for (ConceptSetFilterComponent f : filters) {
161      addRow(sheet, f.getProperty(), f.getOpElement().asStringValue(), f.getValue());
162    }
163  }
164
165}