package cz.linkedlist.http;

import cz.linkedlist.TileInfoService;
import cz.linkedlist.TileSet;
import cz.linkedlist.UTMCode;
import cz.linkedlist.info.ProductInfo;
import cz.linkedlist.info.TileInfo;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.concurrent.ListenableFuture;

import java.time.LocalDate;
import java.util.Arrays;
import java.util.List;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

/**
 * @author Martin Macko <https://github.com/LinkedList>
 */

@SpringBootTest
@RunWith(SpringRunner.class)
public class HttpTileInfoServiceTest {

    @Autowired
    private TileInfoService service;
    @Autowired
    private JdbcTemplate jdbc;

    @Before
    public void init() {
        jdbc.execute("TRUNCATE TABLE cache");
    }

    @Test
    public void downloadTileInfo() {
        final TileInfo tileInfo = service.getTileInfo(new TileSet(UTMCode.of("36MTD"), LocalDate.of(2016, 8, 31)));
        assertThat(tileInfo.getUtmZone(), is(36));
        assertThat(tileInfo.getLatitudeBand(), is("M"));
        assertThat(tileInfo.getGridSquare(), is("TD"));
        assertThat(tileInfo.getCloudyPixelPercentage(), is(0.06D));
        assertThat(tileInfo.getPath(), is("tiles/36/M/TD/2016/8/31/0"));
    }

    @Test
    public void downloadProductInfo() {
        final ProductInfo productInfo = service.getProductInfo(new TileSet(UTMCode.of("36MTD"), LocalDate.of(2016, 8, 31)));
        assertThat(productInfo.getName(), is("S2A_OPER_PRD_MSIL1C_PDMC_20160831T150507_R078_V20160831T080612_20160831T082520"));
    }

    @Test
    @Ignore("TODO Ignore till I figure out how to make junit taskExecutor not reject tasks")
    public void testDownloadTileInfoAndSetToTileSet() {
        final TileSet tileSet = new TileSet(UTMCode.of("36MTD"), LocalDate.of(2016, 8, 31));
        final ListenableFuture<TileSet> f = service.downTileInfo(tileSet);
        f.addCallback(set -> {
            assertThat(set, not(tileSet));
            assertThat(tileSet.getInfo(), not(nullValue()));
            assertThat(tileSet.cloudiness(), is(0.06D));
        }, t -> Assert.fail());
    }

    @Test
    public void testDownloadTileInfoAndSetToTileSets() {
        final TileSet tileSet = new TileSet(UTMCode.of("36MTD"), LocalDate.of(2016, 8, 31));
        final TileSet tileSet2 = new TileSet(UTMCode.of("36MTD"), LocalDate.of(2016, 8, 31));
        final ListenableFuture<List<TileSet>> f = service.downTileInfo(Arrays.asList(tileSet, tileSet2));
        f.addCallback(
                list -> {
                    assertThat(list, hasSize(2));
                    list.forEach(set -> {
                        assertThat(set.getInfo(), not(nullValue()));
                        assertThat(set.cloudiness(), closeTo(0.06D, 0.0D));
                    });
                }, t -> Assert.fail());
    }

    @Test
    public void testDownloadTileInfo() {
        final TileSet tileSet = new TileSet(UTMCode.of("36MTD"), LocalDate.of(2016, 8, 31));
        final ListenableFuture<TileSet> f = service.downTileInfo(tileSet);
        f.addCallback(set -> {
                    assertThat(set.getInfo(), not(nullValue()));
                    assertThat(set.cloudiness(), closeTo(0.06D, 0.0D));
                }
                , throwable -> Assert.fail());
    }

    @Test(expected = RuntimeException.class)
    public void downloadNotExists() {
        service.getTileInfo(new TileSet(UTMCode.of("11AAA"), LocalDate.of(2016, 8, 31)));
    }
}

@@ -3831,11 +3831,205 @@
 );%0A    %7D
+%0A%0A    @Test(expected = RuntimeException.class)%0A    public void downloadNotExistsProductInfo() %7B%0A        service.getProductInfo(new TileSet(UTMCode.of(%2211AAA%22), LocalDate.of(2016, 8, 31)));%0A    %7D
 %0A%7D%0A

Test all the thingzzz :unicorn: