/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.myfaces.test.htmlunit.junit4;

import java.io.IOException;
import java.net.URL;
import java.util.Iterator;

import org.junit.After;
import org.junit.Before;

import com.gargoylesoftware.htmlunit.ElementNotFoundException;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
import com.gargoylesoftware.htmlunit.html.HtmlBody;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlHead;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;



/**
 * <p>Abstract base class for system integration tests based on HtmlUnit.
 * These tests will expect a system property named <code>url</code> to be
 * present, which will define the URL (including the context path, but
 * without a trailing slash) of the application to be tested.</p>
 */

public abstract class AbstractHtmlUnitTestCase {


    // ------------------------------------------------------------ Constructors


    /**
     * <p>Construct a new instance of this test case.</p>
     *
     * @param name Name of the new test case
     */
    public AbstractHtmlUnitTestCase()
    {
    }


    // ------------------------------------------------------ Instance Variables


    /**
     * <p>The most recently retrieved page from the server.</p>
     */
    protected HtmlPage page = null;


    /**
     * <p>The calculated URL for the installed "systest" web application.
     * This value is based on a system property named <code>url</code>,
     * which must be defined as part of the command line that executes
     * each test case.</p>
     */
    protected URL url = null;


    /**
     * <p>The web client for this test case.</p>
     */
    protected WebClient webClient = null;


    // ------------------------------------------------------ Test Setup Methods


    /**
     * <p>Set up the instance variables required for this test case.</p>
     *
     * @exception Exception if an error occurs
     */
    @Before
    protected void setUp() throws Exception {

        // Calculate the URL for the installed "systest" web application
        String url = System.getProperty("url");
        this.url = new URL(url + "/");

        // Initialize HtmlUnit constructs for this test case
        webClient = new WebClient();

    }

    /**
     * <p>Tear down instance variables required by this test case.</p>
     */
    @After
    protected void tearDown() throws Exception {

        page = null;
        url = null;
        webClient = null;

    }



    // ------------------------------------------------------- Protected Methods


    /**
     * <p>Return the body element for the most recently retrieved page.
     * If there is no such element, return <code>null</code>.</p>
     *
     * @exception Exception if an error occurs
     */
    protected HtmlBody body() throws Exception {

        Iterator elements = page.getAllHtmlChildElements();
        while (elements.hasNext()) {
            HtmlElement element = (HtmlElement) elements.next();
            if (element instanceof HtmlBody) {
                return ((HtmlBody) element);
            }
        }
        return (null);

    }


    /**
     * <p>Return the HTML element with the specified <code>id</code> from the
     * most recently retrieved page.  If there is no such element, return
     * <code>null</code>.</p>
     *
     * @param id Identifier of the requested element.
     *
     * @exception Exception if an error occurs
     */
    protected HtmlElement element(String id) throws Exception {

        try {
            return (page.getHtmlElementById(id));
        } catch (ElementNotFoundException e) {
            return (null);
        }

    }


    /**
     * <p>Return the form with the specified <code>id</code> from the most
     * recently retrieved page.  If there is no such form, return
     * <code>null</code>.<p>
     *
     * @param id Identifier of the requested form.
     *
     * @exception Exception if an error occurs
     */
    protected HtmlForm form(String id) throws Exception {

        Iterator forms = page.getForms().iterator();
        while (forms.hasNext()) {
            HtmlForm form = (HtmlForm) forms.next();
            if (id.equals(form.getAttributeValue("id"))) {
                return (form);
            }
        }
        return (null);

    }


    /**
     * <p>Return the head element for the most recently retrieved page.
     * If there is no such element, return <code>null</code>.</p>
     *
     * @exception Exception if an error occurs
     */
    protected HtmlHead head() throws Exception {

        Iterator elements = page.getAllHtmlChildElements();
        while (elements.hasNext()) {
            HtmlElement element = (HtmlElement) elements.next();
            if (element instanceof HtmlHead) {
                return ((HtmlHead) element);
            }
        }
        return (null);

    }


    /**
     * <p>Click the specified hyperlink, and retrieve the subsequent page,
     * saving a reference so that other utility methods may be used to
     * retrieve information from it.</p>
     *
     * @param anchor Anchor component to click
     *
     * @exception IOException if an input/output error occurs
     */
    protected HtmlPage link(HtmlAnchor anchor) throws IOException {

        HtmlPage page = (HtmlPage) anchor.click();
        this.page = page;
        return page;

    }


    /**
     * <p>Return the currently stored page reference.</p>
     */
    protected HtmlPage page() {

        return this.page;

    }


    /**
     * <p>Retrieve and return the page at the specified context relative path.
     * Save a reference to this page so that other utility methods may be used
     * to retrieve information from it.</p>
     *
     * @param path Context relative path
     *
     * @exception IllegalArgumentException if the context relative path
     *  does not begin with a '/' character
     * @exception Exception if a different error occurs
     */
    protected HtmlPage page(String path) throws Exception {

        HtmlPage page = (HtmlPage) webClient.getPage(url(path));
        this.page = page;
        return (page);

    }


    /**
     * <p>Reset the stored page reference to the specified value.  This is
     * useful for scenarios testing resubmit of the same page (simulating the
     * user pressing the back button and then submitting again).</p>
     *
     * @param page Previously saved page to which to reset
     */
    protected void reset(HtmlPage page) {

        this.page = page;

    }


    /**
     * <p>Submit the current page, using the specified component, and retrieve
     * the subsequent page, saving a reference so that other utility methods
     * may be used to retrieve information from it.</p>
     *
     * @param submit Submit button component to click
     *
     * @exception IOException if an input/output error occurs
     */
    protected HtmlPage submit(HtmlSubmitInput submit) throws IOException {

        HtmlPage page = (HtmlPage) submit.click();
        this.page = page;
        return page;

    }


    /**
     * <p>Return the page title from the most recently retrieved page.
     * Any leading and trailing whitespace will be trimmed.</p>
     *
     * @exception Exception if an error occurs
     */
    protected String title() throws Exception {

        return (page.getTitleText().trim());

    }


    /**
     * <p>Calculate and return an absolute URL for the specified context
     * relative path, which must begin with a '/' character.</p>
     *
     * @param path Context relative path
     *
     * @exception IllegalArgumentException if the context relative path
     *  does not begin with a '/' character
     * @exception Exception if a different error ocurs
     */
    protected URL url(String path) throws Exception {

        if (path.charAt(0) != '/') {
            throw new IllegalArgumentException("Context path '" + path
                                               + "' does not start with '/'");
        }
        return new URL(url, path.substring(1));

    }


}
