package org.araymond.joal;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.turn.ttorrent.common.protocol.TrackerMessage.AnnounceRequestMessage.RequestEvent;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.AbstractFileFilter;
import org.araymond.joal.core.client.emulated.BitTorrentClient;
import org.araymond.joal.core.client.emulated.BitTorrentClientConfig;
import org.araymond.joal.core.ttorent.client.ConnectionHandler;
import org.araymond.joal.core.ttorent.client.bandwidth.TorrentWithStats;
import org.araymond.joal.core.ttorent.client.bandwidth.TorrentWithStatsTest;
import org.junit.Test;
import org.mockito.Mockito;

import java.io.File;
import java.net.InetAddress;
import java.net.URL;
import java.net.UnknownHostException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import static org.assertj.core.api.Assertions.fail;

/**
 * Created by raymo on 20/07/2017.
 */
public class StaticClientFilesTester {

    private static final Path clientsPath = Paths.get("resources/clients");
    private static final ObjectMapper mapper = new ObjectMapper();

    private static InetAddress createMockedINet6Address() {
        try {
            return InetAddress.getByName("fd2d:7212:4cd5:2f14:ffff:ffff:ffff:ffff");
        } catch (final UnknownHostException e) {
            throw new IllegalStateException(e);
        }
    }

    private static ConnectionHandler createMockedConnectionHandler(final InetAddress inetAddress) {
        final ConnectionHandler connectionHandler = Mockito.mock(ConnectionHandler.class);
        Mockito.when(connectionHandler.getPort()).thenReturn(46582);
        Mockito.when(connectionHandler.getIpAddress()).thenReturn(inetAddress);
        return connectionHandler;
    }

    @Test
    public void shouldBeDeserializable() {
        FileUtils.listFiles(clientsPath.toFile(), new AcceptAllFileFilter(), null)
                .forEach(file -> {
                    try {
                        final String json = new String(Files.readAllBytes(file.toPath()));
                        final BitTorrentClientConfig clientConfig = mapper.readValue(json, BitTorrentClientConfig.class);
                        final BitTorrentClient client = clientConfig.createClient();
                    } catch (final Exception e) {
                        fail("Exception for client file " + file.getName(), e);
                    }
                });
    }

    @Test
    public void shouldGenerateAnnounceURL() {
        FileUtils.listFiles(clientsPath.toFile(), new AcceptAllFileFilter(), null)
                .forEach(file -> {
                    try {
                        final String json = new String(Files.readAllBytes(file.toPath()));
                        final BitTorrentClientConfig clientConfig = mapper.readValue(json, BitTorrentClientConfig.class);
                        final BitTorrentClient client = clientConfig.createClient();

                        final ConnectionHandler connHandler = createMockedConnectionHandler(createMockedINet6Address());
                        final TorrentWithStats torrent = TorrentWithStatsTest.createMocked();

                        client.buildAnnounceURL(new URL("http://my.tracker.com/announce"), RequestEvent.STARTED, torrent, connHandler);
                    } catch (final Exception e) {
                        fail("Exception for client file " + file.getName(), e);
                    }
                });
    }

    private static class AcceptAllFileFilter extends AbstractFileFilter {
        @Override
        public boolean accept(final File file) {
            return true;
        }
    }
}

@@ -859,16 +859,74 @@
 Paths;%0A%0A
+import static org.assertj.core.api.Assertions.assertThat;%0A
 import s
@@ -2345,16 +2345,994 @@
 lient();
+%0A%0A                        final String query = client.getQuery();%0A                        assertThat(query)%0A                                .contains(%22info_hash=%7Binfohash%7D%22)%0A                                .contains(%22peer_id=%7Bpeerid%7D%22)%0A                                .contains(%22uploaded=%7Buploaded%7D%22)%0A                                .contains(%22downloaded=%7Bdownloaded%7D%22)%0A                                .contains(%22left=%7Bleft%7D%22)%0A                                .contains(%22key=%7Bkey%7D%22)%0A                                .contains(%22event=%7Bevent%7D%22)%0A                                .contains(%22numwant=%7Bnumwant%7D%22);%0A                        if (query.contains(%22ipv6=%22)) assertThat(query).contains(%22ipv6=%7Bipv6%7D%22);%0A                        if (query.contains(%22ip=%22)) assertThat(query).contains(%22ip=%7Bip%7D%22);%0A                        if (query.contains(%22%7Bipv6%7D%22)) assertThat(query).contains(%22ipv6=%7Bipv6%7D%22);%0A                        if (query.contains(%22%7Bip%7D%22)) assertThat(query).contains(%22ip=%7Bip%7D%22);
 %0A       

Enforce StaticClientFilesTester