package org.devgateway.ocds.web.rest.controller.test;

import com.mongodb.DBObject;
import org.apache.commons.io.IOUtils;
import org.devgateway.ocds.persistence.mongo.Organization;
import org.devgateway.ocds.persistence.mongo.repository.ReleaseRepository;
import org.devgateway.ocds.persistence.mongo.spring.ExcelImportService;
import org.devgateway.ocds.web.rest.controller.AverageNumberOfTenderersController;
import org.devgateway.ocds.web.rest.controller.AverageTenderAndAwardPeriodsController;
import org.devgateway.ocds.web.rest.controller.CostEffectivenessVisualsController;
import org.devgateway.ocds.web.rest.controller.request.DefaultFilterPagingRequest;
import org.devgateway.ocds.web.rest.controller.request.GroupingFilterPagingRequest;
import org.devgateway.ocds.web.rest.controller.request.OrganizationSearchRequest;
import org.devgateway.ocds.web.rest.controller.selector.ProcuringEntitySearchController;
import org.devgateway.ocvn.persistence.mongo.dao.ImportFileTypes;
import org.devgateway.toolkit.web.AbstractWebTest;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.aggregation.Fields;

import java.io.IOException;
import java.util.List;

/**
 * @author mihai
 *
 */
public class VNImportAndEndpointsTest extends AbstractWebTest {

    @Autowired
    private ExcelImportService vnExcelImportService;

    @Autowired
    private CostEffectivenessVisualsController costEffectivenessVisualsController;

    @Autowired
    private AverageNumberOfTenderersController averageNumberOfTenderersController;

    @Autowired
    private AverageTenderAndAwardPeriodsController averageTenderAndAwardPeriodsController;

    @Autowired
    private ProcuringEntitySearchController procuringEntitySearchController;

    @Autowired
    private ReleaseRepository releaseRepository;

    public byte[] loadResourceStreamAsByteArray(String name) throws IOException {
        return IOUtils.toByteArray(getClass().getResourceAsStream(name));
    }

    @Before
    public void importTestData() throws IOException, InterruptedException {
        releaseRepository.deleteAll();

        vnExcelImportService.importAllSheets(ImportFileTypes.ALL_FILE_TYPES,
                loadResourceStreamAsByteArray("/testImport/test_egp_Jun21_Import.xlsx"),
                loadResourceStreamAsByteArray("/testImport/test_Location_Table_Geocoded.xlsx"),
                loadResourceStreamAsByteArray("/testImport/test_UM_PUBINSTITU_SUPPLIERS_DQA.xlsx"), true, false);
    }

    @After
    public void tearDown() {
        // be sure to clean up the release collection
        releaseRepository.deleteAll();
    }

    @Test
    public void testCostEffectivenessAwardAmount() {
        List<DBObject> costEffectivenessAwardAmount = costEffectivenessVisualsController
                .costEffectivenessAwardAmount(new DefaultFilterPagingRequest());
        DBObject root = costEffectivenessAwardAmount.get(0);
        int year = (int) root.get(Fields.UNDERSCORE_ID);
        Assert.assertEquals(2014, year);

        double totalAwardAmount = (double) root.get("totalAwardAmount");
        Assert.assertEquals(2000, totalAwardAmount, 0);

    }

    @Test
    public void testCostEffectivenessTenderAmount() {
        List<DBObject> costEffectivenessTenderAmount = costEffectivenessVisualsController
                .costEffectivenessTenderAmount(new GroupingFilterPagingRequest());
        DBObject root = costEffectivenessTenderAmount.get(0);
        int year = (int) root.get(Fields.UNDERSCORE_ID);
        Assert.assertEquals(2012, year);

        double totalAwardAmount = (double) root.get("totalTenderAmount");
        Assert.assertEquals(1000, totalAwardAmount, 0);

    }

    @Test
    public void testAverageNumberOfTenderersController() {
        List<DBObject> averageNumberOfTenderers = averageNumberOfTenderersController.
                averageNumberOfTenderers(new DefaultFilterPagingRequest());

        DBObject root = averageNumberOfTenderers.get(0);
        int year = (int) root.get("year");
        Assert.assertEquals(2013, year);

        double averageNoTenderers = (double) root.get("averageNoTenderers");
        Assert.assertEquals(2, averageNoTenderers, 0);
    }

    @Test
    public void testAverageAwardPeriod() {
        List<DBObject> averageAwardPeriod = averageTenderAndAwardPeriodsController
                .averageAwardPeriod(new DefaultFilterPagingRequest());

        DBObject root = averageAwardPeriod.get(0);
        int year = (int) root.get(Fields.UNDERSCORE_ID);
        Assert.assertEquals(2014, year);

        double n = (double) root.get("averageAwardDays");
        Assert.assertEquals(536, n, 0);
    }

    @Test
    public void testAverageTenderPeriod() {
        List<DBObject> averageTenderPeriod = averageTenderAndAwardPeriodsController
                .averageTenderPeriod(new DefaultFilterPagingRequest());

        DBObject root = averageTenderPeriod.get(0);
        int year = (int) root.get(Fields.UNDERSCORE_ID);
        Assert.assertEquals(2012, year);

        double n = (double) root.get("averageTenderDays");
        Assert.assertEquals(15, n, 0);

        root = averageTenderPeriod.get(1);
        year = (int) root.get(Fields.UNDERSCORE_ID);
        Assert.assertEquals(2013, year);

        n = (double) root.get("averageTenderDays");
        Assert.assertEquals(15, n, 0);
    }

    @Test
    public void testQualityAverageTenderPeriod() {
        List<DBObject> qAverageTenderPeriod = averageTenderAndAwardPeriodsController
                .qualityAverageTenderPeriod(new DefaultFilterPagingRequest());

        DBObject root = qAverageTenderPeriod.get(0);

        int totalTenderWithStartEndDates = (int) root.get("totalTenderWithStartEndDates");
        Assert.assertEquals(2, totalTenderWithStartEndDates);

        int totalTenders = (int) root.get("totalTenders");
        Assert.assertEquals(2, totalTenders);

        double percentageTenderWithStartEndDates = (double) root.get("percentageTenderWithStartEndDates");
        Assert.assertEquals(100, percentageTenderWithStartEndDates, 0);
    }

    @Test
    public void testQualityAverageAwardPeriod() {
        List<DBObject> qAverageTenderPeriod = averageTenderAndAwardPeriodsController
                .qualityAverageAwardPeriod(new DefaultFilterPagingRequest());

        DBObject root = qAverageTenderPeriod.get(0);

        int totalAwardWithStartEndDates = (int) root.get("totalAwardWithStartEndDates");
        Assert.assertEquals(4, totalAwardWithStartEndDates);

        int totalAwards = (int) root.get("totalAwards");
        Assert.assertEquals(4, totalAwards);

        double percentageAwardWithStartEndDates = (double) root.get("percentageAwardWithStartEndDates");
        Assert.assertEquals(100, percentageAwardWithStartEndDates, 0);
    }


    @Test
    public void testProcuringEntitySearchController() {
        List<Organization> procuringEntities = procuringEntitySearchController.searchText(
                new OrganizationSearchRequest());
        Assert.assertEquals(procuringEntities.size(), 1, 0);
    }

}

@@ -1189,16 +1189,63 @@
 owired;%0A
+import org.springframework.cache.CacheManager;%0A
 import o
@@ -1979,16 +1979,71 @@
 itory;%0A%0A
+    @Autowired%0A    private CacheManager cacheManager;%0A%0A
     publ
@@ -2321,24 +2321,233 @@
 leteAll();%0A%0A
+        // clean the cache (we need this especially for endpoints cache)%0A        if (cacheManager != null) %7B%0A            cacheManager.getCacheNames().forEach(c -%3E cacheManager.getCache(c).clear());%0A        %7D%0A%0A
         vnEx

clear cache before each endpoint test.