/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 2005 Bull S.A.
 * Contact: jonas-team@objectweb.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or 1any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */

package org.objectweb.jonas.jonasadmin.test.domain;


import junit.framework.TestSuite;

import org.objectweb.jonas.jonasadmin.test.util.JonasAdminAuth;
import org.objectweb.jonas.jonasadmin.test.util.JonasAdminTestCase;
import org.objectweb.jonas.jonasadmin.test.util.JonasAdminUtils;
import org.xml.sax.SAXException;

import com.meterware.httpunit.HttpUnitOptions;
import com.meterware.httpunit.HttpUnitUtils;
import com.meterware.httpunit.TableCell;
import com.meterware.httpunit.WebLink;
import com.meterware.httpunit.WebResponse;
import com.meterware.httpunit.WebTable;

/**
 * Define a class to add useful methods for test the examples
 *  - Execute the EditDomainAction
 * @author Paul Kemler
 */
public class F_JonasAdminDomain extends JonasAdminTestCase {
	/**
	 * default domain name
	 */
	private static final String DOMAIN_NAME = "jonas";
	/**
	 * default server name
	 */
	private static final String SERVER_NAME = "jonas";
	/**
	 * default jonas domain description in domain.xml
	 */
	private static final String DESCRIPTION = "A domain named jonas";
    /**
     *
     */
    private static final String TITLE_OTHERSERVERS = "Servers in domain";
    /**
     * Domain type set to domainForm by EditDomainAction
     */
    private static final String TITLE_DOMAIN = "Domain";
    /**
     * label.domain.properties
     */
    private static final String TITLE_PROPERTIES = "properties";
    /**
     * label.domain.servers
     */
    private static final String TITLE_SERVERS = "Servers in domain";
    /**
     * message.domain.servers.none
     */
    private static final String MESSAGE_NO_SERVERS = "No other server in this domain!";
    /**
     * label.domain.clusters
     */
    private static final String TITLE_CLUSTERS = "Clusters";
    /**
     * message.domain.clusters.none
     */
    private static final String MESSAGE_NO_CLUSTERS = "No clusters in this domain!";
    /**
     * Main method
     * @param args the arguments
     */
    public static void main(String[] args) {

        String testtorun = null;
        // Get args
        for (int argn = 0; argn < args.length; argn++) {
            String sArg = args[argn];
            if (sArg.equals("-n")) {
                testtorun = args[++argn];
            }
        }
        if (testtorun == null) {
            junit.textui.TestRunner.run(suite());
        } else {
            junit.textui.TestRunner.run(new F_JonasAdminDomain(testtorun));
        }
    }

    /**
     * Get a new TestSuite for this class
     * @return a new TestSuite for this class
     */
    public static TestSuite suite() {
        return new TestSuite(F_JonasAdminDomain.class);
    }

    /**
     * Setup need for these tests
     * jonasAdmin is required
     * @throws Exception if it fails
     */
    protected void setUp() throws Exception {
        super.setUp();

        if (wc.getCurrentPage().getURL() == null) {
            useWar("jonasAdmin");
            // login to jonas admin
            try {
                JonasAdminAuth.doValidAuth(wc, url);
            } catch (Exception e) {
                fail("authentification failed :  " + e);
            }
        } else {
            // if there was an error, the connection must be restablished
            try {
                wc.getFrameContents(FRAME_TREE);
            } catch (Exception e) {
                wc.getResponse(urlLogOut);
                // login to jonas admin
                try {
                    JonasAdminAuth.doValidAuth(wc, url);
                } catch (Exception auth) {
                    fail("authentification failed :  " + auth);
                }
            }
        }
    }


    /**
     * Constructor with a specified name
     * @param s name
     */
    public F_JonasAdminDomain(String s) {
        super(s, URL_JONASADMIN);
    }

    /**
     * Verify if it is the good link of the tree which is selected
     * @param wr The WebResponse of the 'tree' frame
     * @param name A string with the name of the link
     * @return a boolean. True if the name is found in the link, else false.
     */
    private boolean treeControlSelected (WebResponse wr, String name) {
        boolean isSelected = false;     // the result
        int nbSelectedLink = 0;         // number of selected link
        String attribut;                // value of class attribut

        // Get all links
        WebLink[] links;
        try {
            links = wr.getLinks();

            // Search links with the 'tree-control-selected' class attribut
            // and increase nbSelectedLink
            for (int i = 0; i < links.length; i++) {
                attribut = links[i].getAttribute("class");
                if (attribut.indexOf("tree-control-selected") != -1) {
                    nbSelectedLink++;
                }
            }

            if (nbSelectedLink == 1) {
                WebLink link = wr.getLinkWith(name);
                String content = link.getAttribute("class");
                if (content.indexOf("tree-control-selected") != -1) {
                    isSelected = true;
                }
            }
        } catch (SAXException e) {
            fail("No link was found. " + e);
        }

        return isSelected;
    }


    /**
     * Test Succesful Select
     * @throws Exception if it fails
     *
     */
    public void testSuccessfulSelect() throws Exception {

        // Disable errors of javascript
        HttpUnitOptions.setExceptionsThrownOnScriptError(false);

        // Get the frame "tree"
        WebResponse treeFrame = wc.getFrameContents(FRAME_TREE);

        // Create a request
        WebLink link = treeFrame.getLinkWith("Domain");
        link.click();

        // Get the frame "tree"
        treeFrame = wc.getFrameContents(FRAME_TREE);

        // Verify if the attribut class that values "tree-control-selected"
        // it is in a link with "Domain"
        if (!treeControlSelected(treeFrame, "Domain")) {
            fail("Domain is not selected in the tree.");
        }

        // Create a new request for going to another page
        link = treeFrame.getLinkWith("Services");
        link.click();

        // Get the frame "tree"
        treeFrame = wc.getFrameContents(FRAME_TREE);

        // Verify if the attribut class that values "tree-control-selected"
        // it is NOT in a link with "Domain"
        if (treeControlSelected(treeFrame, "Domain")) {
            fail("Domain is selected in the tree.");
        }


        // Create a new request for going to another page
        link = treeFrame.getLinkWith("Domain");
        link.click();

        // Get the frame "tree"
        treeFrame = wc.getFrameContents(FRAME_TREE);

        // Verify if the attribut class that values "tree-control-selected"
        // it is in a link with "Domain"
        if (!treeControlSelected(treeFrame, "Domain")) {
            fail("Domain is not selected in the tree.");
        }

    }

    /**
     * Test Succesful Master Server Link
     * @throws Exception if it fails
     *
     */
    public void testSuccesfulServerLink() throws Exception {

        // The expected link
        String expectedLink = URL_JONASADMIN + "EditJonasServer.do?select=jonas:j2eeType=J2EEServer,name=jonas";

        // Disable errors of javascript
        HttpUnitOptions.setExceptionsThrownOnScriptError(false);

        // Get the frame "tree"
        WebResponse treeFrame = wc.getFrameContents(FRAME_TREE);

        // Create a request
        WebLink link = treeFrame.getLinkWith("Domain");
        link.click();

        // Get the response
        WebResponse wr = wc.getFrameContents(FRAME_CONTENT);

        // Verify the link to the JonasAdmin's server (the master)
        link = wr.getLinks()[0];
        String actualLink = link.getAttribute("href");
        actualLink = HttpUnitUtils.decode(actualLink);
        assertEquals("The link of the JonasAdmin's server is wrong.", expectedLink, actualLink);
    }

    /**
     * Test if Domain presentation is correct
     * @throws Exception if it fails
     *
     */
    public void testDomainProperties() throws Exception {
    	JonasAdminUtils utils = new JonasAdminUtils();
        // Disable errors of javascript
        HttpUnitOptions.setExceptionsThrownOnScriptError(false);

        // Get the frame "tree"
        WebResponse treeFrame = wc.getFrameContents(FRAME_TREE);

        // Create a request
        WebLink link = treeFrame.getLinkWith("Domain");
        link.click();

        // Get the response
        WebResponse wr = wc.getFrameContents(FRAME_CONTENT);

        // Properties table
        // - Title table -
        // We are expecting "Domain properties"
        WebTable table = utils.getTable(wr, 0);
        TableCell cell = table.getTableCell(0, 0);
        String text = cell.getText();
        boolean found;
        if (text.indexOf(TITLE_DOMAIN) == 0 && text.indexOf(TITLE_PROPERTIES) > 0) {
        	found = true;
        } else {
        	found = false;
        }
        assertTrue("Can't find title " + TITLE_DOMAIN + " " + TITLE_PROPERTIES, found);
        // - Table content -
        table = utils.getTable(wr, 1);
        // First row Name jonas
        cell = table.getTableCell(0, 0);
        String propText = cell.getText();
        // step over 2nd cell conataining &nbsp;
        cell = table.getTableCell(0, 2);
        String valuText = cell.getText();
        if (propText.indexOf("Name") >= 0 && valuText.indexOf(DOMAIN_NAME) >= 0) {
        	found = true;
        } else {
        	found = false;
        }
        assertTrue("The Name property is not " + DOMAIN_NAME, found);
        // Next row
        cell = table.getTableCell(1, 0);
        propText = cell.getText();
        // step over 2nd cell conataining &nbsp;
        cell = table.getTableCell(1, 2);
        valuText = cell.getText();
        if (propText.indexOf("Description") >= 0 && valuText.indexOf(DESCRIPTION) >= 0) {
        	found = true;
        } else {
        	found = false;
        }
        assertTrue("The Description property is not " + DESCRIPTION, found);
        // Next row
        cell = table.getTableCell(2, 0);
        propText = cell.getText();
        // step over 2nd cell conataining &nbsp;
        cell = table.getTableCell(2, 2);
        valuText = cell.getText();
        if (propText.indexOf("Master server") >= 0 && valuText.indexOf(SERVER_NAME) >= 0) {
        	found = true;
        } else {
        	found = false;
        }
        assertTrue("The Master server property is not " + SERVER_NAME, found);

        // Servers table
        // - Title table -
        // We are expecting "Servers in domain"
        table = utils.getTable(wr, 3);
        cell = table.getTableCell(0, 0);
        text = cell.getText();
        if (text.indexOf(TITLE_SERVERS) >= 0) {
        	found = true;
        } else {
        	found = false;
        }
        assertTrue("Can't find title " + TITLE_SERVERS, found);
        // - Action zone
        table = utils.getTable(wr, 4);
        cell = table.getTableCell(0, 0);
        text = cell.getText();
        if (text.indexOf("Action") >= 0) {
        	found = true;
        } else {
        	found = false;
        }
        assertTrue("Can't find Action zone", found);
        // Button zone
        table = utils.getTable(wr, 5);
        cell = table.getTableCell(0, 0);
        WebLink[] links = cell.getLinks();
        if (links.length >= 1) {
        	found = true;
        } else {
        	found = false;
        }
        assertTrue("Can't find link in Action zone", found);
        // Servers list
        table = utils.getTable(wr, 7);
        cell = table.getTableCell(0, 0);
        text = cell.getText();
        if (text.indexOf(MESSAGE_NO_SERVERS) >= 0) {
        	found = true;
        } else {
        	found = false;
        }
        assertTrue("Expecting " + MESSAGE_NO_SERVERS + ", found " + text, found);

        // Clusters table
        // - Title table -
        // We are expecting "Clusters"
        table = utils.getTable(wr, 9);
        cell = table.getTableCell(0, 0);
        text = cell.getText();
        if (text.indexOf(TITLE_CLUSTERS) >= 0) {
        	found = true;
        } else {
        	found = false;
        }
        assertTrue("Can't find title " + TITLE_CLUSTERS, found);
        // - Action zone
        table = utils.getTable(wr, 10);
        cell = table.getTableCell(0, 0);
        text = cell.getText();
        if (text.indexOf("Action") >= 0) {
        	found = true;
        } else {
        	found = false;
        }
        assertTrue("Can't find Action zone", found);
        // Button zone
        table = utils.getTable(wr, 11);
        cell = table.getTableCell(0, 0);
        links = cell.getLinks();
        if (links.length >= 1) {
        	found = true;
        } else {
        	found = false;
        }
        assertTrue("Can't find link in Action zone", found);
        // Clusters list
        table = utils.getTable(wr, 13);
        cell = table.getTableCell(0, 0);
        text = cell.getText();
        if (text.indexOf(MESSAGE_NO_CLUSTERS) >= 0) {
        	found = true;
        } else {
        	found = false;
        }
        assertTrue("Expecting " + MESSAGE_NO_CLUSTERS + ", found " + text, found);
    }

    /**
     * Tear Down cleanUp action
     * @throws Exception if an error occurs
     */
    public void tearDown() throws Exception {
        super.tearDown();
    }

}