package de.duehl.basics.datetime.time;

import static org.junit.Assert.*;

import java.util.List;
import java.util.Map;

import org.junit.Ignore;
import org.junit.Test;

import de.duehl.basics.collections.CollectionsHelper;
import de.duehl.basics.system.SystemTools;

public class TimeMeasurementTest {

    @Test (expected = IllegalArgumentException.class)
    public void twoEqualPhases() {
        TimeMeasurement measurement = new TimeMeasurement();
        measurement.addPhases("foo", "foo");
    }

    @Test (expected = IllegalArgumentException.class)
    public void startingUnknownPhase() {
        TimeMeasurement measurement = new TimeMeasurement();
        measurement.addPhases("foo");
        measurement.start("bar");
    }

    @Test (expected = IllegalArgumentException.class)
    public void stoppingUnknownPhase() {
        TimeMeasurement measurement = new TimeMeasurement();
        measurement.addPhases("foo");
        measurement.stop("bar");
    }

    @Test (expected = IllegalArgumentException.class)
    public void stoppingWrongPhase() {
        TimeMeasurement measurement = new TimeMeasurement();
        measurement.addPhases("foo", "bar");
        measurement.start("foo");
        measurement.stop("bar");
    }

    @Test @Ignore // nicht verlässlich die Zeiten
    public void createReport() {
        TimeMeasurement measurement = new TimeMeasurement();
        measurement.addPhases("foo");

        measurement.start("foo");
        SystemTools.sleep(1000);
        measurement.stop("foo");

        SystemTools.sleep(1000);

        measurement.start("foo");
        SystemTools.sleep(1000);
        measurement.stop("foo");

        Map<String, String> runtimeByPhase = measurement.createReport();
        assertEquals(2, runtimeByPhase.keySet().size());
        List<String> keys = CollectionsHelper.getSortedMapStringIndices(runtimeByPhase);
        assertEquals(2, keys.size());

        String idleKey = keys.get(0);
        assertEquals(TimeMeasurement.IDLE, idleKey);
        String fooKey = keys.get(1);
        assertEquals("foo", fooKey);

        String runtimeIdle = runtimeByPhase.get(idleKey);
        assertEquals("00:00:01", runtimeIdle);
        String runtimeFoo = runtimeByPhase.get(fooKey);
        assertEquals("00:00:02", runtimeFoo);
    }

    @Test (expected = IllegalArgumentException.class)
    public void reportAfterInitialisationWithoutAddPhases() {
        TimeMeasurement measurement = new TimeMeasurement();
        measurement.createReport();
    }

    @Test
    public void reportAfterInitialisation() {
        TimeMeasurement measurement = new TimeMeasurement();
        measurement.addPhases("foo");

        Map<String, String> runtimeByPhase = measurement.createReport();
        assertEquals(2, runtimeByPhase.keySet().size());
        List<String> keys = CollectionsHelper.getSortedMapStringIndices(runtimeByPhase);
        assertEquals(2, keys.size());

        String idleKey = keys.get(0);
        assertEquals(TimeMeasurement.IDLE, idleKey);
        String fooKey = keys.get(1);
        assertEquals("foo", fooKey);

        String runtimeIdle = runtimeByPhase.get(idleKey);
        assertEquals("00:00:00", runtimeIdle);
        String runtimeFoo = runtimeByPhase.get(fooKey);
        assertEquals("00:00:00", runtimeFoo);
    }

    @Test  @Ignore // nicht verlässlich die Zeiten
    public void createReportAsLines() {
        TimeMeasurement measurement = new TimeMeasurement();
        measurement.addPhases("foo");

        measurement.start("foo");
        SystemTools.sleep(1000);
        measurement.stop("foo");

        SystemTools.sleep(1000);

        measurement.start("foo");
        SystemTools.sleep(1000);
        measurement.stop("foo");

        List<String> report = measurement.createReportAsLines();
        assertEquals(2, report.size());

        assertEquals(TimeMeasurement.IDLE + "\t" + "00:00:01", report.get(0));
        assertEquals("foo" + "\t" + "00:00:02", report.get(1));
    }

}
