package votorola.a.diff.harvest;

import static org.junit.Assert.*;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.URISyntaxException;
import java.sql.SQLException;
import java.util.concurrent.Semaphore;

import javax.script.ScriptException;

import org.junit.Before;
import org.junit.Test;

import votorola.a.VoteServer;
import votorola.a.diff.harvest.cache.HarvestCache;
import votorola.a.diff.harvest.kick.Kicker;
import votorola.a.diff.harvest.kick.UpdateKick;

public class PipermailHarvesterTest {

    private final static int NUM_PERMITS = 100;

    private final Semaphore numRunning = new Semaphore(NUM_PERMITS);

    private VoteServer.Run vsRun = null;

    @Before
    public void setup() throws IOException, ScriptException, SQLException,
            URISyntaxException {
        vsRun = new VoteServer(System.getProperty("user.name")).new Run(false);
        HarvestCache.init(vsRun);
    }

    @Test
    public void testFrench() throws InterruptedException {
        String[] archives = new String[] {
        // "http://lists.centos.org/pipermail/centos-fr/",
        "https://lists.indymedia.org/pipermail/imc-france-paris/" };

        harvest(archives);
    }

    @Test
    public void testSpanish() throws InterruptedException {
        String[] archives = new String[] { "http://lists.centos.org/pipermail/centos-es/" };

        harvest(archives);
    }

    @Test
    public void testEnglish() throws InterruptedException {
        String[] archives = new String[] {
        // "http://metagovernment.org/pipermail/start_metagovernment.org/"
        // ,
        "http://mail.zelea.com/list/votorola/" };

        harvest(archives);
    }

    @Test
    public void testGerman() throws InterruptedException {
        String[] archives = new String[] { "http://v.polyc0l0r.net/pipermail/votorola/"
//        ,
//         "https://service.piratenpartei.de/pipermail/ag-meinungsfindungstool/"
        };

        harvest(archives);
    }

    @Test
    public void testFaultyUrl() throws InterruptedException {
        String[] archives = new String[] { "http://localhost:1234/some/path/" };

        harvest(archives);
    }

    private void harvest(final String[] urls) throws InterruptedException {
        for (final String url : urls) {
            numRunning.acquire();
            System.out.println("Kicking: " + url);
            Kicker.i().broadcast(
                    UpdateKick.create("Stuff:Pipermail", url,
                            createReporter("Test-Archive", true)));
        }

        while (numRunning.availablePermits() < NUM_PERMITS) {
            Thread.sleep(1000);
        }
    }

    private HarvestReporter createReporter(final String _archive,
            final boolean _verbose) {
        final HarvestReporter reporter = new HarvestReporter() {
            final StringBuilder sb = new StringBuilder();
            final String archive = _archive;

            @Override
            public PrintStream printStream() {
                return new PrintStream(new OutputStream() {
                    @Override
                    public void write(int b) throws IOException {
                        sb.append(b);
                        System.out.write(b);
                    }
                });
            }

            @Override
            public void proccessFinished() {
                numRunning.release();
                System.out.println("Finished: " + archive);
                // TODO improve error handling
                if (sb.toString().contains("failed")) {
                    fail(sb.toString());
                }
            }

        };
        return reporter;
    }

    public static void main(String[] args) {
        try {
            PipermailHarvesterTest test = new PipermailHarvesterTest();
            test.setup();
            test.testEnglish();
        } catch (InterruptedException | IOException | ScriptException | SQLException | URISyntaxException e) {
            e.printStackTrace();
        }
    }

}