package org.pdxfinder.repositories;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.pdxfinder.BaseTest;
import org.pdxfinder.dao.ExternalDataSource;
import org.pdxfinder.dao.Sample;
import org.pdxfinder.dao.Tissue;
import org.pdxfinder.dao.TumorType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.sql.Date;
import java.time.Instant;

/**
 * Testing repository for managing tumor objects
 */
public class SampleRepositoryTest extends BaseTest {

    private final static Logger log = LoggerFactory.getLogger(SampleRepositoryTest.class);
    private String tumorTypeName = "TEST_TUMORTYPE";
    private String extDsName = "TEST_SOURCE";
    private String tissueName = "TEST_TISSUE";

    @Autowired
    private SampleRepository sampleRepository;

    @Autowired
    private TissueRepository tissueRepository;

    @Autowired
    private TumorTypeRepository tumorTypeRepository;

    @Autowired
    private PatientRepository patientRepository;

    @Autowired
    private ExternalDataSourceRepository externalDataSourceRepository;

    @Before
    public void cleanDb() {

        sampleRepository.deleteAll();
        patientRepository.deleteAll();
        externalDataSourceRepository.deleteAll();
        tissueRepository.deleteAll();

        TumorType tumorType = tumorTypeRepository.findByName(tumorTypeName);
        if (tumorType == null) {
            log.debug("Sample type {} not found. Creating", tumorTypeName);
            tumorType = new TumorType(tumorTypeName);
            tumorTypeRepository.save(tumorType);
        }

        ExternalDataSource ds = externalDataSourceRepository.findByName(extDsName);
        if (ds == null) {
            log.debug("External data source {} not found. Creating", extDsName);
            ds = new ExternalDataSource(extDsName, extDsName, extDsName, Date.from(Instant.now()));
            externalDataSourceRepository.save(ds);
        }

        Tissue tissue = tissueRepository.findByName(tissueName);
        if (tissue == null) {
            log.debug("Tissue {} not found. Creating", extDsName);
            tissue = new Tissue(tissueName);
            tissueRepository.save(tissue);
        }

    }

    @Test
    public void createTumorInGraphDb() throws Exception {

        // Sample:
        //   String sourceTumorId
        //   TumorType type
        //   String diagnosis
        //   Tissue originTissue
        //   Tissue tumorSite
        //   String classification
        //   ExternalDataSource externalDataSource

        TumorType tumorType = tumorTypeRepository.findByName(tumorTypeName);
        Tissue tissue = tissueRepository.findByName(tissueName);
        ExternalDataSource externalDataSource = externalDataSourceRepository.findByAbbreviation(extDsName);

        String TEST_TUMOR_ID = "TESTID-1";
        generateTumor(tumorType, tissue, externalDataSource, TEST_TUMOR_ID);

        Sample foundSample = sampleRepository.findBySourceSampleId(TEST_TUMOR_ID);
        Assert.assertNotNull(foundSample);


    }

    @Test
    public void deleteTumor() throws Exception {

        TumorType tumorType = tumorTypeRepository.findByName(tumorTypeName);
        Tissue tissue = tissueRepository.findByName(tissueName);
        ExternalDataSource externalDataSource = externalDataSourceRepository.findByAbbreviation(extDsName);

        String testTumorId = "DELETE_TESTID-1";
        generateTumor(tumorType, tissue, externalDataSource, testTumorId);

        Sample foundSample = sampleRepository.findBySourceSampleId(testTumorId);
        Assert.assertNotNull(foundSample);

        sampleRepository.delete(foundSample);
        foundSample = sampleRepository.findBySourceSampleId(testTumorId);
        Assert.assertNull(foundSample);
    }


    @Test
    public void deleteMultipleTumorsByDatasource() throws Exception {

        TumorType tumorType = tumorTypeRepository.findByName(tumorTypeName);
        Tissue tissue = tissueRepository.findByName(tissueName);
        ExternalDataSource externalDataSource = externalDataSourceRepository.findByAbbreviation(extDsName);

        for (Integer i = 0; i < 20; i++) {
            String testTumorId = "TESTID-" + i;
            generateTumor(tumorType, tissue, externalDataSource, testTumorId);
        }

        Sample foundSample = sampleRepository.findBySourceSampleId("TESTID-12");
        Assert.assertNotNull(foundSample);

        // Added 20 tumors, count should be 20
        Assert.assertEquals(20, sampleRepository.count());

        // Delete all tumors, count should be 0
        sampleRepository.delete(sampleRepository.findByExternalDataSourceAbbreviation(externalDataSource.getAbbreviation()));
        Assert.assertEquals(0, sampleRepository.count());

    }

    private void generateTumor(TumorType tumorType, Tissue tissue, ExternalDataSource externalDataSource, String TEST_TUMOR_ID) {
        Sample sample = new Sample(TEST_TUMOR_ID, tumorType, "TEST_DIAGNOSIS", tissue, tissue, "Surgical Resection", "TEST_CLASSIFICATION", false, externalDataSource);
        sampleRepository.save(sample);
    }


}

@@ -3043,16 +3043,29 @@
 SampleId
+AndDataSource
 (TEST_TU
@@ -3070,16 +3070,54 @@
 TUMOR_ID
+, externalDataSource.getAbbreviation()
 );%0A     
@@ -3660,36 +3660,87 @@
 urceSampleId
-(testTumorId
+AndDataSource(testTumorId, externalDataSource.getAbbreviation()
 );%0A        A
@@ -3879,28 +3879,79 @@
 SampleId
-(testTumorId
+AndDataSource(testTumorId, externalDataSource.getAbbreviation()
 );%0A     
@@ -4576,20 +4576,71 @@
 leId
-(%22TESTID-12%22
+AndDataSource(%22TESTID-12%22, externalDataSource.getAbbreviation()
 );%0A 
@@ -4793,247 +4793,182 @@
 );%0A%0A
+%0A
     
-    // Delete all tumors, count
+%7D%0A//String
  s
-h
 ou
-ld be 0%0A        sampleRepository.delete(sampleRepository.findByExternalDataSourceAbbreviation(externalDataSource.getAbbreviation()));%0A        Assert.assertEquals(0, sampleRepository.count());%0A%0A    %7D%0A
+rceSampleId, TumorType type, String diagnosis, Tissue originTissue, Tissue sampleSite, String extractionMethod, String classification, Boolean normalTissue
 %0A   
@@ -5259,16 +5259,34 @@
 taSource
+.getAbbreviation()
 );%0A     

Add new method to test samples