/*
 * 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.base.junit;

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>
 * 
 * @since 1.0.0
 */
public abstract class AbstractHtmlUnitTestCase
{

    // ------------------------------------------------------------ Constructors

    /**
     * <p>Construct a new instance of this test case.</p>
     */
    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
    {
        Iterable<HtmlElement> elements = page.getHtmlElementDescendants();
        for (HtmlElement element : elements)
        {
            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.getAttribute("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
    {
        Iterable<HtmlElement> elements = page.getHtmlElementDescendants();
        for (HtmlElement element : elements)
        {
            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));

    }

}
