package org.richfaces.testng;

import org.ajax4jsf.template.Template;
import org.ajax4jsf.template.TestConstants;
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 AjaxFormTest extends SeleniumTestBase implements RichSeleniumTest {
    
    private final static String TEST_URL = "pages/ajaxForm/ajaxFormTest.xhtml";
    
    private final static String FORM_ID = "a4j_form";
    
    private static final String STANDART_FORM = "staticForm";
    
    private final static String INNER_INPUT_ID = "inner_name";
    
    private final static String OUTER_INPUT_ID = "outer_name";
    
    private final static String TEST_FIELD_ID = "test_field_name";
    
    private final static String BUTTON_ID = "submit";
    
    private final static String PREV_TEXT = "before submit";
    
    private final static String NEXT_TEXT = "after submit";
    
    private final static String CHECK_ID_AJAXSUBMIT = "ajaxSubmit";
    
    private final static String CHECK_ID_IGNOREDUPRESPONSES = "ignoreDupResponses";
    
    private final static String CHECK_ID_PREPENDID = "prependId";
    
    private final static String CHECK_ID_RENDERED = "rendered";
    
    private final static String PANEL_GROUP = "content";
    
    private final static String RERENDER_ID = "rerender";
    
    private final static String LINK_ID = "link";
    
    @Test
    public void testAttrAjaxSubmit() throws Exception {
	renderPage(Template.SIMPLE);
	
	//clickOnCheckbox(CHECK_ID_AJAXSUBMIT, BUTTON_ID);
	test(BUTTON_ID, INNER_INPUT_ID, STANDART_FORM.concat(":").concat(OUTER_INPUT_ID), TEST_FIELD_ID, true, null, null, null, "testAttrAjaxSubmit");
    }
    
    @Test
    public void testAttrPrependId() {
	renderPage(Template.SIMPLE);
	
	if (!PREV_TEXT.equals(getValueById(getFullComponentId(INNER_INPUT_ID, "1")))) {
	    assertFail(null, null, true, null, "testAttrPrependId");
	}
    }
    
    /*@Test
    public void testAttrIgnoreDupResponses() {
	//TODO: will be implemented in future
    }*/
    
    /*@Test
    public void testAttrTimeout() {
	//TODO: will be implemented in future
    }*/
    
    @Test
    public void testProcessingLinks() {
	renderPage(Template.SIMPLE);
	
	clickOnCheckbox(CHECK_ID_RENDERED, BUTTON_ID, "2");
	clickById(LINK_ID.concat("2"));
	waitForAjaxCompletion();
	if (!NEXT_TEXT.equals(getTextById(TEST_FIELD_ID.concat("2")))) {
	    assertFail(null, null, null, null, "testProcessingLinks");
	}
	
    }
    
    public AjaxFormTest() {
	super(TestConstants.PROTOCOL, TestConstants.HOST, serverPort);
    }
    
    @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);
    }
    
    @AfterMethod(alwaysRun=true)
    public void stopSelenium() {
    	super.stopSelenium();
    }
    
    private String getFullComponentId(String componentId, String index) {
	return FORM_ID.concat(index).concat(":").concat(componentId.concat(index));
    }
    
    private boolean isAjaxSubmitSuccessfull(String innerInputId, String outerInputId) {
	String innerText = getTextById(innerInputId);
	String outerText = getValueById(outerInputId);
	return (NEXT_TEXT.equals(innerText) && (PREV_TEXT.equals(outerText)));
    }
    
    private void submitForm(String buttonId) {
	clickById(buttonId);
    	waitForAjaxCompletion();
    }
    
    private void test(String buttonId, String innerInputId, String outerInputId, String testInputId,
	    	      Boolean ajaxSubmit, Boolean ignoreDupResponses, 
	    	      Integer timeout, Boolean prependId, String testName) {
	setValueById(innerInputId, NEXT_TEXT);
	submitForm(buttonId);
	if (!isAjaxSubmitSuccessfull(testInputId, outerInputId)) {
	    assertFail(ajaxSubmit, ignoreDupResponses, prependId, timeout, testName);
	}
    }
    
    private void assertFail(Boolean ajaxSubmit, Boolean ignoreDupResponses, Boolean prependId, Integer timeout, String testName) {
	 Assert.fail("<a4j:form> [ajaxSubmit=" + ajaxSubmit + " ; ignoreDupResponses=" 
			  + ignoreDupResponses + " ; timeout=" + timeout 
			  + " ; prependId=" + prependId + "] test '" + testName + "' failure.");
    }
    
    private void clickOnCheckbox(String checkId, String bottonId, String index) {
	clickById(checkId.concat(index));
	clickById(bottonId.concat(index));
	waitForAjaxCompletion();
    }
    
    public String getTestUrl() {
	return TEST_URL;
    }
}
