package uk.ac.ebi.atlas.experimentimport;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import uk.ac.ebi.atlas.model.AssayGroup;
import uk.ac.ebi.atlas.model.SampleCharacteristic;
import uk.ac.ebi.atlas.model.experiment.ExperimentConfiguration;
import uk.ac.ebi.atlas.model.experiment.ExperimentDesign;
import uk.ac.ebi.atlas.model.experiment.ExperimentType;

import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
public class ExperimentFilesCrossValidatorTest {
    @Mock
    ExperimentConfiguration experimentConfiguration;

    @Mock
    ExperimentDesign experimentDesign;

    AssayGroup assayGroup = new AssayGroup("g1", "r1", "r2");

    @Before
    public void setUp(){
        when(experimentConfiguration.getExperimentType()).thenReturn(ExperimentType.RNASEQ_MRNA_DIFFERENTIAL);
        when(experimentConfiguration.getAssayGroups()).thenReturn(ImmutableList.of(assayGroup));
    }

    @Test(expected = IllegalStateException.class)
    public void missingFactorsThrow(){
        when(experimentDesign.getFactorValues("r2")).thenReturn(ImmutableMap.of());

        new ExperimentFilesCrossValidator(experimentConfiguration, experimentDesign).factorsNotMissing();
    }

    @Test
    public void presentFactorsPass(){
        when(experimentDesign.getFactorValues("r1")).thenReturn(ImmutableMap.of("type", "value"));
        when(experimentDesign.getFactorValues("r2")).thenReturn(ImmutableMap.of("type", "value"));

        new ExperimentFilesCrossValidator(experimentConfiguration, experimentDesign).factorsNotMissing();
    }


    @Test(expected = IllegalStateException.class)
    public void missingCharacteristicsThrow(){
        when(experimentDesign.getSampleCharacteristics("r2")).thenReturn(ImmutableList.of());

        new ExperimentFilesCrossValidator(experimentConfiguration, experimentDesign).sampleCharacteristicsNotMissing();
    }

    @Test
    public void presentCharacteristicsPass(){
        when(experimentDesign.getSampleCharacteristics("r1")).thenReturn(ImmutableList.of(SampleCharacteristic.create("", "")));
        when(experimentDesign.getSampleCharacteristics("r2")).thenReturn(ImmutableList.of(SampleCharacteristic.create("", "")));

        new ExperimentFilesCrossValidator(experimentConfiguration, experimentDesign).sampleCharacteristicsNotMissing();
    }

    @Test(expected = IllegalStateException.class)
    public void inconsistentFactorsFail()  {
        when(experimentDesign.getFactorValues("r1")).thenReturn(ImmutableMap.of("type", "value_1"));
        when(experimentDesign.getFactorValues("r2")).thenReturn(ImmutableMap.of("type", "value_2"));

        new ExperimentFilesCrossValidator(experimentConfiguration, experimentDesign).factorsConsistentWithinAssay();
    }

    @Test
    public void consistentFactorsPass(){
        when(experimentDesign.getFactorValues("r1")).thenReturn(ImmutableMap.of("type", "value"));
        when(experimentDesign.getFactorValues("r2")).thenReturn(ImmutableMap.of("type", "value"));

        new ExperimentFilesCrossValidator(experimentConfiguration, experimentDesign).factorsConsistentWithinAssay();
    }

    @Test
    public void consistentFactorsPassWithMultipleFactorTypes(){
        when(experimentDesign.getFactorValues("r1")).thenReturn(ImmutableMap.of("type", "value", "type_2", "value_2"));
        when(experimentDesign.getFactorValues("r2")).thenReturn(ImmutableMap.of("type", "value", "type_2", "value_2"));

        new ExperimentFilesCrossValidator(experimentConfiguration, experimentDesign).factorsConsistentWithinAssay();
    }

    @Test(expected = IllegalStateException.class)
    public void inconsistentFactorsFailWithMultipleFactorTypes(){
        when(experimentDesign.getFactorValues("r1")).thenReturn(ImmutableMap.of("type", "value", "type_2", "value_2"));
        when(experimentDesign.getFactorValues("r2")).thenReturn(ImmutableMap.of("type", "value", "type_2", "different_value_2"));

        new ExperimentFilesCrossValidator(experimentConfiguration, experimentDesign).factorsConsistentWithinAssay();
    }

    @Test
    public void blockIsTheSpecialCaseWhereInconsistencyDoesntMatter(){
        when(experimentConfiguration.getExperimentType()).thenReturn(ExperimentType.RNASEQ_MRNA_DIFFERENTIAL);

        when(experimentDesign.getFactorValues("r1")).thenReturn(ImmutableMap.of("type", "value", "block", "value_2"));
        when(experimentDesign.getFactorValues("r2")).thenReturn(ImmutableMap.of("type", "value", "block", "value_2"));

        new ExperimentFilesCrossValidator(experimentConfiguration, experimentDesign).factorsConsistentWithinAssay();

        when(experimentDesign.getFactorValues("r1")).thenReturn(ImmutableMap.of("type", "value", "block", "value_2"));
        when(experimentDesign.getFactorValues("r2")).thenReturn(ImmutableMap.of("type", "value", "block", "different_value_2"));

        new ExperimentFilesCrossValidator(experimentConfiguration, experimentDesign).factorsConsistentWithinAssay();
    }

    @Test(expected = IllegalStateException.class)
    public void blockButBaselineExperimentIsNotFine(){
        when(experimentConfiguration.getExperimentType()).thenReturn(ExperimentType.RNASEQ_MRNA_BASELINE);

        when(experimentDesign.getFactorValues("r1")).thenReturn(ImmutableMap.of("type", "value", "block", "value_2"));
        when(experimentDesign.getFactorValues("r2")).thenReturn(ImmutableMap.of("type", "value", "block", "different_value_2"));

        new ExperimentFilesCrossValidator(experimentConfiguration, experimentDesign).factorsConsistentWithinAssay();
    }
}
@@ -685,32 +685,40 @@
 %7B%0A    @Mock%0A    
+private 
 ExperimentConfig
@@ -765,16 +765,24 @@
 ock%0A    
+private 
 Experime
@@ -817,29 +817,51 @@
     
-AssayGroup assayGroup
+private static final AssayGroup ASSAY_GROUP
  = n
@@ -1129,18 +1129,19 @@
 .of(
-assayGroup
+ASSAY_GROUP
 ));%0A
@@ -2558,3241 +2558,6 @@
    %7D
-%0A%0A    @Test(expected = IllegalStateException.class)%0A    public void inconsistentFactorsFail()  %7B%0A        when(experimentDesign.getFactorValues(%22r1%22)).thenReturn(ImmutableMap.of(%22type%22, %22value_1%22));%0A        when(experimentDesign.getFactorValues(%22r2%22)).thenReturn(ImmutableMap.of(%22type%22, %22value_2%22));%0A%0A        new ExperimentFilesCrossValidator(experimentConfiguration, experimentDesign).factorsConsistentWithinAssay();%0A    %7D%0A%0A    @Test%0A    public void consistentFactorsPass()%7B%0A        when(experimentDesign.getFactorValues(%22r1%22)).thenReturn(ImmutableMap.of(%22type%22, %22value%22));%0A        when(experimentDesign.getFactorValues(%22r2%22)).thenReturn(ImmutableMap.of(%22type%22, %22value%22));%0A%0A        new ExperimentFilesCrossValidator(experimentConfiguration, experimentDesign).factorsConsistentWithinAssay();%0A    %7D%0A%0A    @Test%0A    public void consistentFactorsPassWithMultipleFactorTypes()%7B%0A        when(experimentDesign.getFactorValues(%22r1%22)).thenReturn(ImmutableMap.of(%22type%22, %22value%22, %22type_2%22, %22value_2%22));%0A        when(experimentDesign.getFactorValues(%22r2%22)).thenReturn(ImmutableMap.of(%22type%22, %22value%22, %22type_2%22, %22value_2%22));%0A%0A        new ExperimentFilesCrossValidator(experimentConfiguration, experimentDesign).factorsConsistentWithinAssay();%0A    %7D%0A%0A    @Test(expected = IllegalStateException.class)%0A    public void inconsistentFactorsFailWithMultipleFactorTypes()%7B%0A        when(experimentDesign.getFactorValues(%22r1%22)).thenReturn(ImmutableMap.of(%22type%22, %22value%22, %22type_2%22, %22value_2%22));%0A        when(experimentDesign.getFactorValues(%22r2%22)).thenReturn(ImmutableMap.of(%22type%22, %22value%22, %22type_2%22, %22different_value_2%22));%0A%0A        new ExperimentFilesCrossValidator(experimentConfiguration, experimentDesign).factorsConsistentWithinAssay();%0A    %7D%0A%0A    @Test%0A    public void blockIsTheSpecialCaseWhereInconsistencyDoesntMatter()%7B%0A        when(experimentConfiguration.getExperimentType()).thenReturn(ExperimentType.RNASEQ_MRNA_DIFFERENTIAL);%0A%0A        when(experimentDesign.getFactorValues(%22r1%22)).thenReturn(ImmutableMap.of(%22type%22, %22value%22, %22block%22, %22value_2%22));%0A        when(experimentDesign.getFactorValues(%22r2%22)).thenReturn(ImmutableMap.of(%22type%22, %22value%22, %22block%22, %22value_2%22));%0A%0A        new ExperimentFilesCrossValidator(experimentConfiguration, experimentDesign).factorsConsistentWithinAssay();%0A%0A        when(experimentDesign.getFactorValues(%22r1%22)).thenReturn(ImmutableMap.of(%22type%22, %22value%22, %22block%22, %22value_2%22));%0A        when(experimentDesign.getFactorValues(%22r2%22)).thenReturn(ImmutableMap.of(%22type%22, %22value%22, %22block%22, %22different_value_2%22));%0A%0A        new ExperimentFilesCrossValidator(experimentConfiguration, experimentDesign).factorsConsistentWithinAssay();%0A    %7D%0A%0A    @Test(expected = IllegalStateException.class)%0A    public void blockButBaselineExperimentIsNotFine()%7B%0A        when(experimentConfiguration.getExperimentType()).thenReturn(ExperimentType.RNASEQ_MRNA_BASELINE);%0A%0A        when(experimentDesign.getFactorValues(%22r1%22)).thenReturn(ImmutableMap.of(%22type%22, %22value%22, %22block%22, %22value_2%22));%0A        when(experimentDesign.getFactorValues(%22r2%22)).thenReturn(ImmutableMap.of(%22type%22, %22value%22, %22block%22, %22different_value_2%22));%0A%0A        new ExperimentFilesCrossValidator(experimentConfiguration, experimentDesign).factorsConsistentWithinAssay();%0A    %7D
 %0A%7D

Remove check that ensures factor values are unique within an assay group (remove tests)