package be.iminds.ilabt.jfed.experimenter_gui.bugreporting;

import be.iminds.ilabt.jfed.CorePreferencesModule;
import be.iminds.ilabt.jfed.bugreport.*;
import be.iminds.ilabt.jfed.call_log_output.SerializableApiCallDetails;
import be.iminds.ilabt.jfed.highlevel.HighLevelModule;
import be.iminds.ilabt.jfed.highlevel.LowLevelModule;
import be.iminds.ilabt.jfed.highlevel.MockGeniUserModule;
import be.iminds.ilabt.jfed.highlevel.SfaOnlyExperimentModule;
import be.iminds.ilabt.jfed.util.IOUtils;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;

import javax.inject.Inject;
import java.io.IOException;
import java.io.StringReader;
import java.util.List;

import static org.testng.Assert.*;

/**
 * TestBugReport
 */
@Test
@Guice(modules = {HighLevelModule.class, LowLevelModule.class, MockGeniUserModule.class, CorePreferencesModule.class, SfaOnlyExperimentModule.class})
public class TestBugReport {

    @Inject
    BugReportReaderFactory bugReportReaderFactory;

    @DataProvider(name = "testBugReports")
    public static Object[][] getBugReports() throws IOException {
        return new Object[][]{{IOUtils.resourceToString("bugReportA.xml", TestBugReport.class)}};
    }

    //TODO: reenable test!
    @Test(dataProvider = "testBugReports", enabled = false)
    public void testBugReport(String input) throws Exception {

        BugReportReader bugReportReader = bugReportReaderFactory.createBugReportReader(new StringReader(input));

        BugReport bugReport = bugReportReader.call();
        List<Integer> apiCallDetails = bugReport.getApiCallDetailIds();

        assertNotNull(apiCallDetails);
        assertFalse(apiCallDetails.isEmpty());

        assertNotNull(bugReport.getDescription());
        assertNotNull(bugReport.getVersion());
        assertNotNull(bugReport.getEnvironment());
        assertNotNull(bugReport.getReporterUrn());
        assertNotNull(bugReport.getMail());
        assertNotNull(bugReport.getLoggedInUserInfo());
        assertNotNull(bugReport.getPreferences());

        assertNotNull(bugReport.getApiCallDetailIds());
        assertFalse(bugReport.getApiCallDetailIds().isEmpty());
        assertEquals(bugReport.getApiCallDetailIds().size(), 6);

        List<LogLine> logLines = bugReport.getLogLines();
        assertNotNull(logLines);
        assertFalse(logLines.isEmpty());
        assertEquals(logLines.size(), 11);
        for (int i = 0; i < 11; i++) {
            LogLine l = logLines.get(i);
            assertNotNull(l);
            if (i == 7 || i == 8)
                assertNotNull(l.getException(), "null for logline " + i + ": " + l);
            else
                assertNull(l.getException(), "not null for logline " + i + ": " + l);
            assertNotNull(l.getTime());
            assertNotNull(l.getClassName());
            assertNotNull(l.getLevel());
            assertNotNull(l.getMessage());
            assertNotNull(l.getThreadName());
            assertTrue(l.getTime().getEpochSecond() > 0);
        }

        List<ConnectivityTestResult> connectivityTests = bugReport.getConnectivityTestResults();
        assertNotNull(connectivityTests);
        assertFalse(connectivityTests.isEmpty());
        assertEquals(connectivityTests.size(), 6);
        for (int i = 0; i < 6; i++) {
            ConnectivityTestResult c = connectivityTests.get(i);
            assertNotNull(c);
            if (i == 3)
                assertNotNull(c.getException(), "null for BRConnectivityTest " + i + ": " + c);
            else
                assertNull(c.getException(), "not null for BRConnectivityTest " + i + ": " + c);
            assertNotNull(c.getMessage());
            assertNotNull(c.getName());
            assertNotNull(c.getStatus());
        }

        assertNotNull(bugReport.getSlices());
        assertFalse(bugReport.getSlices().isEmpty());
        assertEquals(bugReport.getSlices().size(), 4);
        for (int i = 0; i < 4; i++) {
            Slice s = bugReport.getSlices().get(i);
            assertNotNull(s);
            assertNotNull(s.getSliceUrn());
            if (i == 2) {
                assertNotNull(s.getSlivers(), "null for BRSlice " + i + ": " + s);
                assertFalse(s.getSlivers().isEmpty());
                assertEquals(s.getSlivers().size(), 4);
                for (int j = 0; j < 4; j++) {
                    Sliver sliver = s.getSlivers().get(j);
                    assertNotNull(sliver);
                    assertNotNull(sliver.getCurrentStatus());
                    assertNotNull(sliver.getSliverStatus());
                    assertNotNull(sliver.getSliverUrn());
                    assertNotNull(sliver.getComponents());
                    assertFalse(sliver.getComponents().isEmpty());
                    assertEquals(sliver.getComponents().size(), 2);
                }
            } else
                assertNull(s.getSlivers(), "not null for BRSlice " + i + ": " + s);
        }
    }
}
