package nl.thehyve.ocdu.validators.crossChecks;

import nl.thehyve.ocdu.models.OCEntities.ClinicalData;
import nl.thehyve.ocdu.models.OcDefinitions.CRFDefinition;
import nl.thehyve.ocdu.models.OcDefinitions.MetaData;
import nl.thehyve.ocdu.models.errors.MandatoryItemInCrfMissing;
import nl.thehyve.ocdu.models.errors.ValidationErrorMessage;

import java.util.*;

/**
 * Created by piotrzakrzewski on 11/05/16.
 */
public class MandatoryInCrfCrossCheck implements ClinicalDataCrossCheck {
    @Override
    public ValidationErrorMessage getCorrespondingError(List<ClinicalData> data, MetaData metaData) {
        HashMap<String, Set<String>> mandatoryMap = getMandatoryMap(data, metaData);
        HashMap<String, Set<String>> presentMap = getPresentMap(data);
        MandatoryItemInCrfMissing error = new MandatoryItemInCrfMissing();
        for (String crfId : mandatoryMap.keySet()) {
            Set<String> expected = mandatoryMap.get(crfId);
            Set<String> found = presentMap.get(crfId);
            expected.stream().filter(expectedItem -> !found.contains(expectedItem)).forEach(missing -> {
                error.addOffendingValue("CRF: " + crfId + " requires item: " + missing);
            });
        }
        if (error.getOffendingValues().size() > 0)
            return error;
        else return null;
    }

    private HashMap<String, Set<String>> getPresentMap(List<ClinicalData> data) {
        HashMap<String, Set<String>> presentMap = new HashMap<>();
        data.stream().forEach(clinicalData -> {
            String crfId = clinicalData.getCrfName() + clinicalData.getCrfVersion();
            if (!presentMap.containsKey(crfId)) {
                Set<String> presentItems = new HashSet<>();
                presentItems.add(clinicalData.getItem());
                presentMap.put(crfId, presentItems);
            } else {
                Set<String> presentItems = presentMap.get(crfId);
                presentItems.add(clinicalData.getItem());
            }
        });
        return presentMap;
    }

    private HashMap<String, Set<String>> getMandatoryMap(List<ClinicalData> data, MetaData metaData) {
        HashMap<String, Set<String>> mandatoryMap = new HashMap<>();
        data.stream().forEach(clinicalData -> {
            String eventName = clinicalData.getEventName();
            String crfName = clinicalData.getCrfName();
            String crfVersion = clinicalData.getCrfVersion();
            CRFDefinition matching = getMatchingCrf(eventName, crfName, crfVersion, metaData);
            if (matching != null) { // Missing CRF or Event are  separate errors
                Set<String> expected = matching.getMandatoryItemNames();
                mandatoryMap.put(crfName + crfVersion, expected);
            }
        });
        return mandatoryMap;
    }




}

@@ -825,24 +825,1170 @@
 fMissing();%0A
+        reportMissingColumns(mandatoryMap, presentMap, error);%0A        reportMissingValues(mandatoryMap, data, error);%0A        if (error.getOffendingValues().size() %3E 0)%0A            return error;%0A        else return null;%0A    %7D%0A%0A    private void reportMissingValues(HashMap%3CString, Set%3CString%3E%3E mandatoryMap, List%3CClinicalData%3E data, MandatoryItemInCrfMissing error) %7B%0A        data.stream().forEach(clinicalData -%3E %7B%0A            String item = clinicalData.getItem();%0A            String crfId = clinicalData.getCrfName() + clinicalData.getCrfVersion();%0A            Set%3CString%3E mandatory = mandatoryMap.get(crfId);%0A            String value = clinicalData.getValue();%0A            if (mandatory != null && mandatory.contains(item) && value.equals(%22%22)) %7B // is mandatory and value is empty%0A                error.addOffendingValue(%22Item: %22 + item + %22 cannot be empty as it is mandatory in CRF: %22 + crfId + %22 but was empty for subject: %22 + clinicalData.getSsid());%0A            %7D%0A        %7D);%0A    %7D%0A%0A%0A    private void reportMissingColumns(HashMap%3CString, Set%3CString%3E%3E mandatoryMap, HashMap%3CString, Set%3CString%3E%3E presentMap, ValidationErrorMessage error) %7B%0A
         for 
@@ -2024,24 +2024,24 @@
 keySet()) %7B%0A
-
             
@@ -2367,111 +2367,8 @@
   %7D%0A
-        if (error.getOffendingValues().size() %3E 0)%0A            return error;%0A        else return null;%0A
     
@@ -3846,20 +3846,20 @@
 oryMap;%0A
+
     %7D%0A%0A%0A
 %0A%0A%7D%0A
@@ -3854,12 +3854,10 @@
     %7D%0A%0A%0A
-%0A%0A
 %7D%0A

Implement reporting empty values for mandatory items as errors