package be.iminds.ilabt.jfed.lowlevel.api.test;

import be.iminds.ilabt.jfed.call_log_output.LogOutput;
import be.iminds.ilabt.jfed.log.Logger;
import be.iminds.ilabt.jfed.lowlevel.GeniUserProvider;
import be.iminds.ilabt.jfed.lowlevel.TestbedInfoSource;
import be.iminds.ilabt.jfed.lowlevel.connection.JFedConnectionProvider;
import be.iminds.ilabt.jfed.preferences.JFedPreferences;
import be.iminds.ilabt.jfed.testing.base.ApiTest;
import be.iminds.ilabt.jfed.testing.base.ApiTestResult;
import be.iminds.ilabt.jfed.util.TargetAuthority;
import org.testng.annotations.Test;

import java.util.regex.Pattern;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;

public class TestMultiNodeLoginTest {

    //AssertionError

    @Test
    public void regexDemo() {
        assertThat("ok=5".matches("ok=5"), is(true));
        assertThat("ok=5".matches("ok=[^0]"), is(true));
        assertThat("aa ok=5 aa".matches("ok=[^0]"), is(false));
        assertThat("ABCok=5DEF".matches("ok=[^0]"), is(false));
        assertThat("ABC\nok=5\nDEF\n".matches("ok=[^0]"), is(false));
        assertThat("ok=0".matches("ok=[^0]"), is(false));
        assertThat("ABC\nok=01\nDEF".matches("ok=[^0]"), is(false));

        assertThat("ok=5".matches(".*ok=[^0].*"), is(true));
        assertThat("aa ok=5 aa".matches(".*ok=[^0].*"), is(true));
        assertThat("ABCok=5DEF".matches(".*ok=[^0].*"), is(true));
        assertThat("ABC\nok=5\nDEF\n".matches(".*ok=[^0].*"), is(false)); //!!!!!!!
        assertThat("ok=0".matches(".*ok=[^0].*"), is(false));
        assertThat("ABC\nok=01\nDEF".matches(".*ok=[^0].*"), is(false));

        Pattern notOk = Pattern.compile("ok=[^0]");
        assertThat(notOk.matcher("ok=5").find(), is(true));
        assertThat(notOk.matcher("aa ok=5 aa").find(), is(true));
        assertThat(notOk.matcher("ABCok=5DEF").find(), is(true));
        assertThat(notOk.matcher("ABC\nok=5\nDEF\n").find(), is(true));
        assertThat(notOk.matcher("ok=0").find(), is(false));
        assertThat(notOk.matcher("ABC\nok=01\nDEF").find(), is(false));
    }
    @Test
    public void testRegex1() {
        ApiTest test = createTestTest();
        String ansibleSuccessWord = null;
        String ansibleWarningWord = null;
        String ansibleFailureWord = null;
        String ansibleSuccessRegex = "ok=[^0]";
        String ansibleFailureRegex = "failed=[^0]";
        String ansibleWarningRegex = "unreachable=[^0]";

        String output =
                "blabla\n" +
                        "blabla ok=5\n" +
                        "blibli\n" +
                        "failed=0 and unreachable=0 blabla\n" +
                        "blabla\n" +
                        "blablabla";

        TestMultiNodeLogin.checkAnsibleOutput(output, test,
                ansibleSuccessWord, ansibleWarningWord, ansibleFailureWord,
                ansibleSuccessRegex, ansibleWarningRegex, ansibleFailureRegex);

        assertThat(test.getCurrentResultState(), is(equalTo(LogOutput.TestResultState.SUCCESS)));
    }

    @Test
    public void testRegex2() {
        ApiTest test = createTestTest();
        String ansibleSuccessWord = null;
        String ansibleWarningWord = null;
        String ansibleFailureWord = null;
        String ansibleSuccessRegex = "ok=[^0]";
        String ansibleFailureRegex = "failed=[^0]";
        String ansibleWarningRegex = "unreachable=[^0]";

        String output =
                "blabla\n" +
                        "blabla ok=5\n" +
                        "blibli\n" +
                        "failed=0 and unreachable=1 blabla\n" +
                        "blabla\n" +
                        "blablabla";

        TestMultiNodeLogin.checkAnsibleOutput(output, test,
                ansibleSuccessWord, ansibleWarningWord, ansibleFailureWord,
                ansibleSuccessRegex, ansibleWarningRegex, ansibleFailureRegex);

        assertThat(test.getCurrentResultState(), is(equalTo(LogOutput.TestResultState.WARN)));
    }

    @Test
//    @Test(expectedExceptions = {AssertionError.class})
    public void testRegex3() {
        ApiTest test = createTestTest();
        String ansibleSuccessWord = null;
        String ansibleWarningWord = null;
        String ansibleFailureWord = null;
        String ansibleSuccessRegex = "ok=[^0]";
        String ansibleFailureRegex = "failed=[^0]";
        String ansibleWarningRegex = "unreachable=[^0]";

        String output =
                "blabla\n" +
                        "blabla ok=0\n" +
                        "blibli\n" +
                        "failed=0 and unreachable=0 blabla\n" +
                        "blabla\n" +
                        "blablabla";

        test.setErrorsNotFatal();
        TestMultiNodeLogin.checkAnsibleOutput(output, test,
                ansibleSuccessWord, ansibleWarningWord, ansibleFailureWord,
                ansibleSuccessRegex, ansibleWarningRegex, ansibleFailureRegex);

        assertThat(test.getCurrentResultState(), is(equalTo(LogOutput.TestResultState.FAILED)));
    }

    @Test
    public void testRegex4() {
        ApiTest test = createTestTest();
        String ansibleSuccessWord = null;
        String ansibleWarningWord = null;
        String ansibleFailureWord = null;
        String ansibleSuccessRegex = "ok=[^0]";
        String ansibleFailureRegex = "failed=[^0]";
        String ansibleWarningRegex = "unreachable=[^0]";

        String output =
                "blabla\n" +
                        "blabla ok=5\n" +
                        "blibli\n" +
                        "failed=1 and unreachable=0 blabla\n" +
                        "blabla\n" +
                        "blablabla";

        test.setErrorsNotFatal();
        TestMultiNodeLogin.checkAnsibleOutput(output, test,
                ansibleSuccessWord, ansibleWarningWord, ansibleFailureWord,
                ansibleSuccessRegex, ansibleWarningRegex, ansibleFailureRegex);

        assertThat(test.getCurrentResultState(), is(equalTo(LogOutput.TestResultState.FAILED)));
    }


    private static ApiTest createTestTest() {
        Logger logger = null;
        TargetAuthority testedAuthority = null;
        GeniUserProvider geniUserProvider = null;
        JFedConnectionProvider connectionProvider = null;
        TestbedInfoSource testbedInfoSource = null;
        JFedPreferences jFedPreferences = null;

        return new ApiTest(logger, testedAuthority, geniUserProvider, connectionProvider,
                testbedInfoSource, jFedPreferences) {
            {
                this.currentTestResult = new ApiTestResult.ApiTestMethodResult() {
                    { state = LogOutput.TestResultState.SUCCESS; }
                };
            }

            @Override
            protected String getTestDescription() {
                return "Test test";
            }

            @Override
            public void setUp() throws Exception {

            }
        };
    }
}