package nl.thehyve.ocdu.validators.clinicalDataChecks;

import nl.thehyve.ocdu.models.OcDefinitions.ItemDefinition;
import nl.thehyve.ocdu.models.OcDefinitions.MetaData;
import nl.thehyve.ocdu.models.OCEntities.ClinicalData;
import nl.thehyve.ocdu.models.OcDefinitions.CRFDefinition;
import nl.thehyve.ocdu.models.errors.CRFDoesNotExist;
import nl.thehyve.ocdu.models.errors.ValidationErrorMessage;
import org.openclinica.ws.beans.StudySubjectWithEventsType;

import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by piotrzakrzewski on 04/05/16.
 */
public class CrfExistsCrossCheck implements ClinicalDataCrossCheck {
    @Override
    public ValidationErrorMessage getCorrespondingError(List<ClinicalData> data, MetaData metaData, Map<ClinicalData, ItemDefinition> itemDefMap, List<StudySubjectWithEventsType> studySubjectWithEventsTypeList, Map<ClinicalData, Boolean> shownMap, Map<String, Set<CRFDefinition>> eventMap) {
        List<ClinicalData> crfNotExistsOffenders = getCrfNotExistsOffenders(data, eventMap);
        if (crfNotExistsOffenders.size() > 0) {
            CRFDoesNotExist error = new CRFDoesNotExist();
            List<String> offendingNames = new ArrayList<>();
            crfNotExistsOffenders.stream().forEach(clinicalData -> {
                String crf = clinicalData.getCrfName();
                String eventName = clinicalData.getEventName();
                String version = clinicalData.getCrfVersion();
                String msg = "CRF: " + crf + " version: " + version + " in event: " + eventName + " for subject: "
                        + clinicalData.getSsid();
                if (!offendingNames.contains(msg)) offendingNames.add(msg);
            });
            error.addAllOffendingValues(offendingNames);
            return error;
        } else return null;
    }


    private List<ClinicalData> getCrfNotExistsOffenders(List<ClinicalData> data, Map<String, Set<CRFDefinition>> eventMap) {
        return data.stream().filter(clinicalData -> {
            Set<CRFDefinition> valid = eventMap.get(clinicalData.getEventName());
            if (valid == null) return false; // CRF Could not be verified is a separate class
            String crf = clinicalData.getCrfName();
            String version = clinicalData.getCrfVersion();
            List<CRFDefinition> matching = valid.stream()
                    .filter(crfDefinition -> crfDefinition.getName().equals(crf) && crfDefinition.getVersion().equals(version)).collect(Collectors.toList());
            return matching.size() == 0;
        }).collect(Collectors.toList());
    }


}

@@ -392,16 +392,61 @@
 essage;%0A
+import org.apache.commons.lang3.StringUtils;%0A
 import o
@@ -1390,25 +1390,23 @@
  String 
-e
 ve
-ntName
+rsion
  = clini
@@ -1420,51 +1420,278 @@
 .get
-EventName();%0A                String version
+CrfVersion();%0A                if (StringUtils.isBlank(crf)) %7B%0A                    crf = %22(LEFT BLANK)%22;%0A                %7D%0A                if (StringUtils.isBlank(version)) %7B%0A                    version = %22(LEFT BLANK)%22;%0A                %7D%0A                String eventName
  = c
@@ -1701,38 +1701,38 @@
 icalData.get
-CrfVersion
+EventName
 ();%0A
+%0A
             

Improve error message for CRFExists check