package uk.ac.ebi.subs.api.services;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import uk.ac.ebi.subs.repository.model.Submission;
import uk.ac.ebi.subs.repository.repos.SubmissionRepository;
import uk.ac.ebi.subs.validator.data.SingleValidationResult;
import uk.ac.ebi.subs.validator.data.ValidationResult;
import uk.ac.ebi.subs.validator.data.structures.GlobalValidationStatus;
import uk.ac.ebi.subs.validator.data.structures.SingleValidationResultStatus;
import uk.ac.ebi.subs.validator.data.structures.ValidationAuthor;
import uk.ac.ebi.subs.validator.repository.ValidationResultRepository;

import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Created by karoly on 11/07/2017.
 */
@Service
public class ValidationResultServiceImpl implements ValidationResultService {

    private ValidationResultRepository validationResultRepository;
    private SubmissionRepository submissionRepository;

    @Autowired
    public ValidationResultServiceImpl(ValidationResultRepository validationResultRepository, SubmissionRepository submissionRepository) {
        this.validationResultRepository = validationResultRepository;
        this.submissionRepository = submissionRepository;
    }

    @Override
    public List<ValidationResult> getValidationResultBySubmissionId(String submissionId) {
        return validationResultRepository.findAllBySubmissionId(submissionId);
    }

    @Override
    public boolean isValidationFinishedAndPassed(String submissionStatusId) {
        Submission submission = submissionRepository.findBySubmissionStatusId(submissionStatusId);
        List<ValidationResult> validationResults = getValidationResultBySubmissionId(submission.getId());

        return validationResults.size() > 0 && isValidationCompleted(validationResults) && isValidationPassed(validationResults);
    }

    private boolean isValidationCompleted(List<ValidationResult> validationResults) {
        return validationResults.stream().filter(
                validationResult -> validationResult.getValidationStatus() != GlobalValidationStatus.Complete)
                .findAny()
                .orElse(null) == null;
    }

    private boolean isValidationPassed(List<ValidationResult> validationResults) {
        for (ValidationResult validationResult : validationResults) {
            Map<ValidationAuthor, List<SingleValidationResult>> expectedResults = validationResult.getExpectedResults();
            Set<ValidationAuthor> authors = expectedResults.keySet();
            for (ValidationAuthor validationAuthor : authors) {
                List<SingleValidationResult> singleValidationResults = expectedResults.get(validationAuthor);
                if (singleValidationResults.size() == 0) {
                    return false;
                }
                boolean isPassed = singleValidationResults.stream()
                        .filter(singleValidationResult -> singleValidationResult.getValidationStatus().equals(SingleValidationResultStatus.Error))
                        .findFirst()
                        .orElse(null) == null;
                if (!isPassed) {
                    return false;
                }
            }
        }

        return true;
    }
}

@@ -657,16 +657,42 @@
 itory;%0A%0A
+import java.util.HashSet;%0A
 import j
@@ -2316,32 +2316,235 @@
 ationResults) %7B%0A
+        Set%3CValidationAuthor%3E relevantAuthorsForSample = new HashSet%3C%3E();%0A        relevantAuthorsForSample.add(ValidationAuthor.Core);%0A        relevantAuthorsForSample.add(ValidationAuthor.Biosamples);%0A%0A
         for (Val
@@ -2714,24 +2714,25 @@
 dResults();%0A
+%0A
             
@@ -2723,35 +2723,35 @@
 );%0A%0A            
-Set
+Map
 %3CValidationAutho
@@ -2755,46 +2755,92 @@
 thor
-%3E a
+,String%3E outcomeByA
 uthor
-s
  = 
-expectedResults.keySet
+validationResult.getOverallValidationOutcomeByAuthor
 ();%0A
+%0A
     
@@ -2851,261 +2851,337 @@
     
-for (ValidationAuthor validationAuthor : authors) %7B%0A                List%3CSingleValidationResult%3E singleValidationResults = expectedResults.get(validationAuthor);%0A                if (singleValidationResults.size() == 0) %7B%0A                    return false
+if (outcomeByAuthor.isEmpty())%7B%0A                return false;%0A            %7D%0A%0A            boolean validatedDocumentIsSample = outcomeByAuthor.containsKey(ValidationAuthor.Biosamples);%0A%0A            for (Map.Entry%3CValidationAuthor,String%3E entry : outcomeByAuthor.entrySet())%7B%0A                ValidationAuthor author = entry.getKey()
 ;%0A  
@@ -3197,225 +3197,138 @@
     
- 
-%7D%0A                boolean isPassed = singleValidationResults.stream()%0A                        .filter(singleValidationResult -%3E singleValidationResult.getValidationStatus().equals(SingleValidationResultStatus.Err
+ String outcome = entry.getValue();%0A%0A                if (validatedDocumentIsSample && !relevantAuthorsForSample.contains(auth
 or))
+%7B
 %0A   
@@ -3348,72 +3348,136 @@
     
-    .findFirst()%0A                        .orElse(null) == null
+continue;%0A                %7D%0A%0A                boolean hasError = SingleValidationResultStatus.Error.toString().equals(outcome)
 ;%0A
+%0A
     
@@ -3496,17 +3496,16 @@
 if (
-!isPassed
+hasError
 ) %7B%0A
@@ -3548,32 +3548,34 @@
               %7D%0A
+%0A%0A
             %7D%0A  

update logic to use overall status, and add different criteria for biosamples