package org.richfaces.testng;

import org.ajax4jsf.template.Template;
import org.richfaces.RichSeleniumTest;
import org.richfaces.SeleniumTestBase;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

public class ProgressBarTest extends SeleniumTestBase implements RichSeleniumTest {

    public ProgressBarTest() {
        super("http", "localhost", serverPort);
    }

    /**
     * This method are invoking before selenium tests started
     */
    @BeforeMethod
    @Parameters({"browser", "filterPrefix"})
    public void startSelenium(String browser, String filterPrefix) {
    	super.startSelenium(browser, filterPrefix);
    }
    
    
    @BeforeMethod
    @Parameters({"loadStyleStrategy", "loadScriptStrategy"})
    protected void loadConfiguration(String loadStyleStrategy, String loadScriptStrategy) throws Exception {
	super.loadConfiguration(loadStyleStrategy, loadScriptStrategy);
    }

    /**
     * This method are invoking after selenium tests completed
     */
    @AfterMethod(alwaysRun=true)
    public void stopSelenium() {
        super.stopSelenium();
    }

    @Test
    public void testProgressBarComponent() {
        _testProgressBarComponent(Template.SIMPLE);
        _testProgressBarComponent(Template.DATA_TABLE);
        _testProgressBarComponent(Template.MODAL_PANEL);
    }

    private void _testProgressBarComponent(Template template) {

        renderPage(template);

        String parentId = getParentId() + "_form:";

        String progressBarId = parentId + "progressBar1";
        int value = getProgressBarValue(progressBarId);
        Assert.assertTrue(value < 0, "Progress value should be negative");
        String text = getTextById(progressBarId);
        writeStatus("Check if process not started");
        Assert.assertTrue(text.startsWith("Process not started"), "Initial facet does not appear");

        writeStatus("Enable polling");
        enableProgressBar(progressBarId, true);

        pause(5000, progressBarId);

        writeStatus("Disable polling");
        enableProgressBar(progressBarId, false);

        writeStatus("Check label");
        text = getTextById(progressBarId + ":remain");
        Assert.assertTrue(text.endsWith("%"), "Percent label doesnot appear");

        writeStatus("Check value");
        value = getProgressBarValue(progressBarId);
        Assert.assertTrue(value > 0, "Progress value should be positive");

        writeStatus("Enable polling");
        enableProgressBar(progressBarId, true);

        pause(5000, progressBarId);
        writeStatus("Check value");
        Assert.assertTrue((getProgressBarValue(progressBarId).intValue() != value),
                "Progress has been terminated abnormal");

        writeStatus("Disable polling");
        enableProgressBar(progressBarId, false);

        value = getProgressBarValue(progressBarId);
        pause(1500, progressBarId);
        writeStatus("Check value");
        Assert.assertTrue(getProgressBarValue(progressBarId) == value,
                "Progress didnt stop after progressBar disabling");

        clickById(parentId + "_complete");
        waitForAjaxCompletion();
        writeStatus("Check if process completed");
        text = getTextById(progressBarId);
        Assert.assertTrue(text.startsWith("Process completed"), "Comlete facet does not appear");

        // - Test client mode

        writeStatus("Check value");
        progressBarId = parentId + "progressBar2";
        value = getProgressBarValue(progressBarId);
        Assert.assertTrue(value == -5, "Progress value should be -5 ");

        text = getTextById(progressBarId);
        writeStatus("Check if process not started");
        Assert.assertTrue(text.startsWith("Process not started"), "Initial facet does not appear");

        setProgressBarValue(progressBarId, 20);
        value = getProgressBarValue(progressBarId);
        writeStatus("Check value");
        Assert.assertTrue(value == 20, "Progress value should be 20 ");

        setProgressBarValue(progressBarId, 60);
        value = getProgressBarValue(progressBarId);
        writeStatus("Check value");
        Assert.assertTrue(value == 60, "Progress value should be 60");

        clickById(parentId + "_reset");
        waitForAjaxCompletion();

    }

    private void enableProgressBar(String id, boolean enable) {
        invokeFromComponent(id, (enable ? "enable" : "disable"), null);
    }

    private void setProgressBarValue(String id, Object value) {
        invokeFromComponent(id, "setValue", value);
    }

    private Integer getProgressBarValue(String id) {
        String value = invokeFromComponent(id, "getValue", null); // runScript(script.toString());
        Integer v = Integer.parseInt(value);
        return v;
    }

    public String getTestUrl() {
        return "pages/progressBar/progressBarTest.xhtml";
    }

}
