package uk.ac.ebi.atlas.experimentimport;

import org.apache.solr.client.solrj.SolrServerException;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import uk.ac.ebi.atlas.controllers.ResourceNotFoundException;
import uk.ac.ebi.atlas.experimentimport.analytics.ScxaAnalyticsLoaderFactory;
import uk.ac.ebi.atlas.model.experiment.ExperimentType;
import uk.ac.ebi.atlas.resource.DataFileHub;

import javax.inject.Inject;
import java.io.IOException;

import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasProperty;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assume.assumeThat;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml", "classpath:dispatcher-servlet.xml"})
public class ExperimentCrudIT {

    @Spy
    @Inject
    private SingleCellExperimentChecker experimentCheckerSpy;

    // Used to check the DB
    @Inject
    private JdbcTemplate jdbcTemplate;

    @Inject
    private ScxaAnalyticsLoaderFactory analyticsLoaderFactory;

    @Inject
    private DataFileHub dataFileHub;

    @Inject
    private ScxaExperimentDao experimentDao;

    @Inject
    private ExperimentCrudFactory experimentCrudFactory;

    private ExperimentCrud subject;

    @Before
    public void setUp() throws IOException {
        MockitoAnnotations.initMocks(this);
        subject = experimentCrudFactory.create(experimentDao, experimentCheckerSpy, analyticsLoaderFactory);
    }

    public static final String SINGLE_CELL_ACCESSION = "E-GEOD-106540";

    @After
    public void tryCleanUp() {
        tryDelete(SINGLE_CELL_ACCESSION);
    }

    private boolean tryDelete(String accession) {
        try{
            subject.deleteExperiment(accession);
            return true;
        } catch (ResourceNotFoundException e){
            return false;
        }
    }

    @Test(expected=ResourceNotFoundException.class)
    public void deleteNonExistentExperimentThrowsResourceNotFoundException() {
        subject.deleteExperiment("FOOBAR");
    }

    @Test
    public void importReloadDeleteExperiment() throws IOException, SolrServerException {
        testImportNewImportExistingAndDelete(
                SINGLE_CELL_ACCESSION, ExperimentType.SINGLE_CELL_RNASEQ_MRNA_BASELINE);
        verify(experimentCheckerSpy, times(2))
                .checkAllFiles(SINGLE_CELL_ACCESSION, ExperimentType.SINGLE_CELL_RNASEQ_MRNA_BASELINE);
    }

    @Test
    public void findAllExperimentsFindsPrivateExperiemtns() throws Exception {
        subject.importExperiment(SINGLE_CELL_ACCESSION, true);
        assertThat(
                subject.findAllExperiments(),
                hasItem(hasProperty("experimentAccession", is(SINGLE_CELL_ACCESSION))));
    }

    public void testImportNewImportExistingAndDelete(String experimentAccession, ExperimentType experimentType) throws IOException, SolrServerException {
        importNewExperimentInsertsDB(experimentAccession, experimentType);
        importExistingExperimentUpdatesDB(experimentAccession, experimentType);
        deleteExperimentDeletesDB(experimentAccession);
    }

    public void importNewExperimentInsertsDB(String experimentAccession, ExperimentType experimentType) throws IOException {
        assumeThat(experimentCount(experimentAccession), is(0));
        assumeThat(expressionsCount(experimentAccession), is(0));

        subject.importExperiment(experimentAccession, false);
        assertThat(experimentCount(experimentAccession), is(1));
    }

    public void importExistingExperimentUpdatesDB(String experimentAccession, ExperimentType experimentType) throws IOException {
        ExperimentDTO originalExperimentDTO = subject.findExperiment(experimentAccession);
        subject.importExperiment(experimentAccession, false);
        assertThat(experimentCount(experimentAccession), is(1));

        if (experimentType.isDifferential()) {
            assertThat(expressionsCount(experimentAccession), is(1));
        }

        ExperimentDTO newExperimentDTO = subject.findExperiment(experimentAccession);
        assertThat(originalExperimentDTO.getAccessKey(), is(newExperimentDTO.getAccessKey()));
    }

    public void deleteExperimentDeletesDB(String experimentAccession) {
        subject.deleteExperiment(experimentAccession);
        assertThat(experimentCount(experimentAccession), is(0));
        assertThat(expressionsCount(experimentAccession), is(0));
    }

    private int experimentCount(String accession) {
        return jdbcTemplate.queryForObject(
                "SELECT COUNT(*) from scxa_experiment WHERE accession=?", Integer.class, accession);
    }

    private int expressionsCount(String accession) {
        return jdbcTemplate.queryForObject(
                "SELECT COUNT(*) from scxa_analytics WHERE experiment_accession=?", Integer.class, accession);
    }

}

@@ -40,65 +40,8 @@
 t;%0A%0A
-import org.apache.solr.client.solrj.SolrServerException;%0A
 impo
@@ -56,24 +56,24 @@
 unit.After;%0A
+
 import org.j
@@ -653,53 +653,8 @@
 ype;
-%0Aimport uk.ac.ebi.atlas.resource.DataFileHub;
 %0A%0Aim
@@ -1458,58 +1458,8 @@
 y;%0A%0A
-    @Inject%0A    private DataFileHub dataFileHub;%0A%0A
     
@@ -1654,35 +1654,16 @@
  setUp()
- throws IOException
  %7B%0A     
@@ -2465,37 +2465,16 @@
 xception
-, SolrServerException
  %7B%0A     
@@ -2827,12 +2827,12 @@
 peri
-emtn
+ment
 s() 
@@ -2864,32 +2864,42 @@
   subject.import
+SingleCell
 Experiment(SINGL
@@ -3219,29 +3219,8 @@
 tion
-, SolrServerException
  %7B%0A 
@@ -3274,32 +3274,16 @@
 ccession
-, experimentType
 );%0A     
@@ -3412,32 +3412,32 @@
 ession);%0A    %7D%0A%0A
+
     public void 
@@ -3495,39 +3495,8 @@
 sion
-, ExperimentType experimentType
 ) th

Clean a bit code and use the single cell import method