/*
 * Copyright (C) 2017 University of Pittsburgh.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301  USA
 */
package edu.cmu.tetrad.algcomparison;

import edu.cmu.tetrad.algcomparison.algorithm.Algorithms;
import edu.cmu.tetrad.algcomparison.algorithm.oracle.pag.Gfci;
import edu.cmu.tetrad.algcomparison.graph.RandomForward;
import edu.cmu.tetrad.algcomparison.independence.FisherZ;
import edu.cmu.tetrad.algcomparison.score.SemBicScore;
import edu.cmu.tetrad.algcomparison.simulation.SemSimulation;
import edu.cmu.tetrad.algcomparison.simulation.Simulations;
import edu.cmu.tetrad.algcomparison.statistic.*;
import edu.cmu.tetrad.util.Parameters;
import edu.cmu.tetrad.util.Params;
import org.junit.ClassRule;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;

import static java.lang.System.out;

/**
 * Nov 14, 2017 5:24:51 PM
 *
 * @author Kevin V. Bui (kvb2@pitt.edu)
 */
public class TimeoutComparisonTest {

    @ClassRule
    public static TemporaryFolder tmpDir = new TemporaryFolder();

    public TimeoutComparisonTest() {
    }

    /**
     * Test of setComparisonGraph method, of class TimeoutComparison.
     *
     * @throws IOException
     */
    @Ignore
    @Test
    public void testTimeoutComparison() throws IOException {
        Parameters parameters = TimeoutComparisonTest.getParameters();
        Statistics statistics = TimeoutComparisonTest.getStatistics();
        Algorithms algorithms = TimeoutComparisonTest.getAlgorithms();
        Simulations simulations = TimeoutComparisonTest.getSimulations();

        String resultsPath = TimeoutComparisonTest.tmpDir.newFolder("comparison").toString();

        TimeoutComparison comparisonEngine = TimeoutComparisonTest.getTetradComparisonEngine();
        comparisonEngine.compareFromSimulations(resultsPath, simulations, algorithms, statistics, parameters, 60, TimeUnit.SECONDS);

        out.println("================================================================================");
        out.println("Output File:");
        out.println("================================================================================");
        Path outputFile = Paths.get(resultsPath, "Comparison.txt");
        if (Files.exists(outputFile)) {
            try (Stream<String> stream = Files.lines(outputFile)) {
                stream.forEach(out::println);
            }
        }
        out.println("================================================================================");
    }

    private static TimeoutComparison getTetradComparisonEngine() {
        TimeoutComparison comparison = new TimeoutComparison();
        comparison.setShowAlgorithmIndices(true);
        comparison.setShowSimulationIndices(true);
        comparison.setSortByUtility(true);
        comparison.setShowUtilities(true);
        comparison.setParallelized(true);

        return comparison;
    }

    private static Simulations getSimulations() {
        Simulations simulations = new Simulations();
        simulations.add(new SemSimulation(new RandomForward()));

        return simulations;
    }

    private static Algorithms getAlgorithms() {
        Algorithms algorithms = new Algorithms();
        algorithms.add(new Gfci(new FisherZ(), new SemBicScore()));

        return algorithms;
    }

    private static Statistics getStatistics() {
        Statistics statistics = new Statistics();
        statistics.add(new AdjacencyPrecision());
        statistics.add(new AdjacencyRecall());
        statistics.add(new ArrowheadPrecision());
        statistics.add(new ArrowheadRecall());
        statistics.add(new MathewsCorrAdj());
        statistics.add(new MathewsCorrArrow());
        statistics.add(new F1Adj());
        statistics.add(new F1Arrow());
        statistics.add(new Shd());
        statistics.add(new ElapsedCpuTime());

        return statistics;
    }

    private static Parameters getParameters() {
        Parameters parameters = new Parameters();
        parameters.set(Params.NUM_RUNS, 1);
        parameters.set(Params.NUM_MEASURES, 100);
        parameters.set(Params.AVG_DEGREE, 4, 6);
        parameters.set(Params.SAMPLE_SIZE, 250000);
        parameters.set(Params.ALPHA, 1e-4, 1e-3, 1e-2);

        return parameters;
    }

}
