package org.rug.simpletests.persistence;

import org.junit.jupiter.api.Tag;
import org.rug.data.smells.ArchitecturalSmell;
import org.rug.persistence.CondensedGraphGenerator;
import org.rug.persistence.PersistenceHub;
import org.rug.persistence.SmellCharacteristicsGenerator;
import org.rug.persistence.TrackGraphGenerator;
import org.rug.tracker.ASmellTracker;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.rug.simpletests.TestData.antlr;
import static org.rug.simpletests.TestData.trackASOutputDir;

@Tag("unitTests")
public class PersistenceHubTest {


    ASmellTracker getTracker() throws IOException, ClassNotFoundException {

        ASmellTracker tracker;
            tracker = new ASmellTracker();
            antlr.forEach(version -> {
                var smells = antlr.getArchitecturalSmellsIn(version);
                smells.forEach(ArchitecturalSmell::calculateCharacteristics);
                tracker.track(smells, version);
            });

        return tracker;
    }


    void testSendTo() throws IOException {
        PersistenceHub.clearAll();
        var outfile = Paths.get(trackASOutputDir,antlr.getName(), "smells-characteristics-new.csv");
        var condensedGraph = Paths.get(trackASOutputDir,antlr.getName(), "condesedGraph-new.graphml");
        PersistenceHub.register(new SmellCharacteristicsGenerator(outfile.toString(), antlr));
        PersistenceHub.register(new CondensedGraphGenerator(condensedGraph.toString()));
        var tracker = new ASmellTracker();
        var v1 = antlr.getVersionWith(1);
        var v2 = antlr.getVersionWith(2);

        var smells = antlr.getArchitecturalSmellsIn(v1);
        smells.forEach(ArchitecturalSmell::calculateCharacteristics);
        tracker.track(antlr.getArchitecturalSmellsIn(v1), v1);

        smells = antlr.getArchitecturalSmellsIn(v2);
        smells.forEach(ArchitecturalSmell::calculateCharacteristics);
        tracker.track(antlr.getArchitecturalSmellsIn(v2), v2);

        PersistenceHub.sendToAndWrite(SmellCharacteristicsGenerator.class, tracker);
        PersistenceHub.sendToAndWrite(CondensedGraphGenerator.class, tracker);
        PersistenceHub.closeAll();
        var lines = Files.readAllLines(outfile);
        assertEquals(7, lines.size());
        outfile.toFile().delete();
        PersistenceHub.clearAll();
    }


    void testPerformanceCharacteristicsFileWriting() throws IOException, ClassNotFoundException {
        PersistenceHub.clearAll();
        var outfile = Paths.get(trackASOutputDir,antlr.getName(), "smells-characteristics-new.csv");
        var trackGraph = Paths.get(trackASOutputDir,antlr.getName(), "trackgraph-new.graphml");
        PersistenceHub.register(new TrackGraphGenerator(trackGraph.toString()));
        PersistenceHub.register(new SmellCharacteristicsGenerator(outfile.toString(), antlr));

        var tracker = getTracker();

        var start = System.nanoTime();
        PersistenceHub.sendToAndWrite(SmellCharacteristicsGenerator.class, tracker);
        PersistenceHub.sendToAndWrite(TrackGraphGenerator.class, tracker);
        PersistenceHub.closeAll();
        var end = System.nanoTime();
        var elapsedSecs = (end - start) / 1e9d;
        System.out.println(String.format("Elapsed saving time: %.3f", elapsedSecs));

        var lines = Files.readAllLines(outfile);
        System.out.println(String.format("Elapsed saving time per record: %.5f", elapsedSecs/lines.size()));
        assertEquals(2328, lines.size());
        assertTrue(elapsedSecs < 3.1); // 3.7 with single-off writing
        PersistenceHub.clearAll();
    }
}
