/**
 * 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.joram;

import javax.management.MBeanServerConnection;
import javax.management.ObjectName;

import junit.framework.TestSuite;

import org.objectweb.jonas.jonasadmin.test.service.container.F_JonasAdminEjbContainer;
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 com.meterware.httpunit.HttpUnitOptions;
import com.meterware.httpunit.SubmitButton;
import com.meterware.httpunit.TableCell;
import com.meterware.httpunit.WebForm;
import com.meterware.httpunit.WebLink;
import com.meterware.httpunit.WebResponse;
import com.meterware.httpunit.WebTable;

/**
 * Class for testing JORAM destinations
 * @author Paul Kemler
 *
 */
public class F_JonasAdminJoramDestination extends JonasAdminTestCase {

    /**
     * URL of the Joram Platform
     */
    private static final String URL_JONASADMIN_JORAM = "EditJoramPlatform.do";

    /**
     * URL of the Joram Servers
     */
    private static final String URL_JONASADMIN_JORAM_SERVERS = "joramplatform/joramservers.jsp";

    /**
     * URL of "Create Jms Destination"
     */
    private static final String URL_JONASADMIN_JORAM_CREATE_DESTINATION = "CreateJoramDestination.do";

    /**
     * URL of the Remove Button
     */
    private static final String URL_JONASADMIN_JORAM_REMOVE = "RemoveConfirmDestinations.do";

    /**
     * URL of the 'Used By' tab for a topic
     */
    private static final String URL_JONASADMIN_TOPIC_USED_BY = "joramplatform/topicUsedBy.jsp";

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

    /**
     * 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_JonasAdminJoramDestination(testtorun));
        }
    }

    /**
     * Get a new TestSuite for this class
     * @return a new TestSuite for this class
     */
    public static TestSuite suite() {
        return new TestSuite(F_JonasAdminJoramDestination.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);
                }
            }
        }
    }

    /**
     * Test the creation of a new topic
     * @throws Exception if error occurs
     *
     */
    public void testCreateNewTopic() throws Exception {

        WebResponse wr;
        WebLink link;
        WebTable table;
        String createDestinationPage;
        /*
         * To get some utils for WebTable
         */
        JonasAdminUtils utils = new JonasAdminUtils();

        // Disable errors of javascript
        HttpUnitOptions.setExceptionsThrownOnScriptError(false);
        // Disable exception thrown on error status
        HttpUnitOptions.setExceptionsThrownOnErrorStatus(false);

        if (jProp.isResource()) {
            // Joram platform is in jonas
            //if (isRarLoaded("joram_for_jonas_ra")) {
            if (isJoramRar()) {
                // Go to Joram Platform
                wr = wc.getFrameContents(FRAME_TREE);
                link = wr.getFirstMatchingLink(WebLink.MATCH_URL_STRING, URL_JONASADMIN_JORAM);
                link.click();
                wr = wc.getFrameContents(FRAME_CONTENT);

                // Go to Joram Servers
                link = wr.getFirstMatchingLink(WebLink.MATCH_URL_STRING, URL_JONASADMIN_JORAM_SERVERS);
                link.click();
                wr = wc.getFrameContents(FRAME_CONTENT);

                // Go to Local Server
                WebTable localTable = utils.getTable(wr, 1);
                link = localTable.getTableCell(0, 0).getLinks()[0];
                if (link == null) {
                    throw new IllegalStateException("No link was found to a local server in the 'Joram servers' page. ");
                }
                link.click();
                wr = wc.getFrameContents(FRAME_CONTENT);

                // Go to Create JMS Destination
                link = wr.getFirstMatchingLink(WebLink.MATCH_URL_STRING, URL_JONASADMIN_JORAM_CREATE_DESTINATION);
                link.click();
                wr = wc.getFrameContents(FRAME_CONTENT);

                createDestinationPage = wr.getText();    // For comparing with the forwarded page after the creation
                // Find a name
                String topicName = "new_topic_";
                int topicId = 0;
                boolean found = false;
                while (!found) {
                    if (!isTopic(topicName + topicId)) {
                        topicName = topicName + topicId;
                        found = true;
                    }
                    topicId++;
                }

                // Create a new topic
                createTopic(wr, topicName);

                wr = wc.getFrameContents(FRAME_CONTENT);

                // Verify topic is created
                assertTrue("The '" + topicName + "' topic was not created. ", isTopic(topicName));

                // Verify the forwarded page
                //assertEquals("The 'New Destination' page has changed. ", createDestinationPage, wr.getText());
                // This asserion can't be verified for the moment as the 'New destination' page has th following
                // <script language="JavaScript">refreshTree("/jonasAdmin/viewTree.do?select=domain*joramplatform*joramlocalserver&s=0.???????");</script>
            }
        }

    }

    /**
     * Test the creation of a new queue
     * @throws Exception if error occurs
     *
     */
    public void testCreateNewQueue() throws Exception {

        WebResponse wr;
        WebLink link;
        WebTable table;
        String createDestinationPage;
        /*
         * To get some utils for WebTable
         */
        JonasAdminUtils utils = new JonasAdminUtils();

        // Disable errors of javascript
        HttpUnitOptions.setExceptionsThrownOnScriptError(false);
        // Disable exception thrown on error status
        HttpUnitOptions.setExceptionsThrownOnErrorStatus(false);


        if (jProp.isResource()) {
            // Joram platform is in jonas
            //if (isRarLoaded("joram_for_jonas_ra")) {
            if (isJoramRar()) {
                // Go to Joram Platform
                wr = wc.getFrameContents(FRAME_TREE);
                link = wr.getFirstMatchingLink(WebLink.MATCH_URL_STRING, URL_JONASADMIN_JORAM);
                link.click();
                wr = wc.getFrameContents(FRAME_CONTENT);

                // Go to Joram Servers
                link = wr.getFirstMatchingLink(WebLink.MATCH_URL_STRING, URL_JONASADMIN_JORAM_SERVERS);
                link.click();
                wr = wc.getFrameContents(FRAME_CONTENT);

                // Go to Local Server
                WebTable localTable = utils.getTable(wr, 1);
                link = localTable.getTableCell(0, 0).getLinks()[0];
                if (link == null) {
                    throw new IllegalStateException("No link was found to a local server in the 'Joram servers' page. ");
                }
                link.click();
                wr = wc.getFrameContents(FRAME_CONTENT);

                // Go to Create JMS Destination
                link = wr.getFirstMatchingLink(WebLink.MATCH_URL_STRING, URL_JONASADMIN_JORAM_CREATE_DESTINATION);
                link.click();
                wr = wc.getFrameContents(FRAME_CONTENT);

                createDestinationPage = wr.getText();    // For comparing with the forwarded page after the creation
                // Find a name
                String queueName = "new_queue_";
                int queueId = 0;
                boolean found = false;
                while (!found) {
                    if (!isQueue(queueName + queueId)) {
                        queueName = queueName + queueId;
                        found = true;
                    }
                    queueId++;
                }

                // Create a new queue
                createQueue(wr, queueName);

                wr = wc.getFrameContents(FRAME_CONTENT);

                // Verify queue is created
                assertTrue("The '" + queueName + "' queue was not created. ", isQueue(queueName));

                // Verify the forwarded page
                // assertEquals("The 'New Destination' page has changed. ", createDestinationPage, wr.getText());
                // This asserion can't be verified for the moment as the 'New destination' page has th following
                // <script language="JavaScript">refreshTree("/jonasAdmin/viewTree.do?select=domain*joramplatform*joramlocalserver&s=0.05622878568562584");</script>
            } else {

            	System.out.println("------joram jar not loaded");
            }
        }

    }

    /**
     * Test to delete a topic
     * @throws Exception if error occurs
     *
     */
    public void testDeleteTopic() throws Exception {

        WebResponse wr;
        WebLink link;
        WebTable table;
        /*
         * To get some utils for WebTable
         */
        JonasAdminUtils utils = new JonasAdminUtils();

        // Disable errors of javascript
        HttpUnitOptions.setExceptionsThrownOnScriptError(false);
        // Disable exception thrown on error status
        HttpUnitOptions.setExceptionsThrownOnErrorStatus(false);

        if (jProp.isResource()) {
            // Joram platform is in jonas
            //if (isRarLoaded("joram_for_jonas_ra")) {
            if (isJoramRar()) {
                // Find a name
                String topicName = "new_topic_";
                int topicId = 0;
                boolean found = false;
                while (!found) {
                    if (!isQueue(topicName + topicId)) {
                        topicName = topicName + topicId;
                        found = true;
                    }
                    topicId++;
                }

                // Create a topic
                createTopic(topicName, getLocalServerId());

                // Go to Joram Platform
                wr = wc.getFrameContents(FRAME_TREE);
                link = wr.getFirstMatchingLink(WebLink.MATCH_URL_STRING, URL_JONASADMIN_JORAM);
                link.click();
                wr = wc.getFrameContents(FRAME_CONTENT);

                // Go to Joram Servers
                link = wr.getFirstMatchingLink(WebLink.MATCH_URL_STRING, URL_JONASADMIN_JORAM_SERVERS);
                link.click();
                wr = wc.getFrameContents(FRAME_CONTENT);

                // Go to Local Server
                WebTable localTable = utils.getTable(wr, 1);
                link = localTable.getTableCell(0, 0).getLinks()[0];
                if (link == null) {
                    throw new IllegalStateException("No link was found to a local server in the 'Joram servers' page. ");
                }
                link.click();
                wr = wc.getFrameContents(FRAME_CONTENT);

                // Delete the created JMS Destination
                WebForm removeDestinationForm = wr.getForms()[0];
                SubmitButton button = removeDestinationForm.getSubmitButtons()[0];
                removeDestinationForm.setCheckbox("selectedItems", topicName, true);
                button.click();

                wr = wc.getFrameContents(FRAME_CONTENT);

                // Confirm
                link = wr.getFirstMatchingLink(WebLink.MATCH_URL_STRING, URL_JONASADMIN_JORAM_REMOVE);
                link.click();
                wr = wc.getFrameContents(FRAME_CONTENT);

                // Verify topic is deleted
                assertTrue("The '" + topicName + "' topic always exists. ", isTopic(topicName));

                // Verify console is updated
                assertTrue("The '" + topicName + "' topic was found in jonasAdmin after deleting. ", wr.getText().indexOf(topicName) == -1);
            }
        }

    }

    /**
     * Test to delete a queue
     * @throws Exception if error occurs
     *
     */
    public void testDeleteQueue() throws Exception {

        WebResponse wr;
        WebLink link;
        WebTable table;
        /*
         * To get some utils for WebTable
         */
        JonasAdminUtils utils = new JonasAdminUtils();

        // Disable errors of javascript
        HttpUnitOptions.setExceptionsThrownOnScriptError(false);
        // Disable exception thrown on error status
        HttpUnitOptions.setExceptionsThrownOnErrorStatus(false);

        if (jProp.isResource()) {
            // Joram platform is in jonas
            //if (isRarLoaded("joram_for_jonas_ra")) {
            if (isJoramRar()) {
                // Find a name
                String queueName = "new_queue_";
                int queueId = 0;
                boolean found = false;
                while (!found) {
                    if (!isQueue(queueName + queueId)) {
                        queueName = queueName + queueId;
                        found = true;
                    }
                    queueId++;
                }

                // Create a queue
                createQueue(queueName, getLocalServerId());

                // Go to Joram Platform
                wr = wc.getFrameContents(FRAME_TREE);
                link = wr.getFirstMatchingLink(WebLink.MATCH_URL_STRING, URL_JONASADMIN_JORAM);
                link.click();
                wr = wc.getFrameContents(FRAME_CONTENT);

                // Go to Joram Servers
                link = wr.getFirstMatchingLink(WebLink.MATCH_URL_STRING, URL_JONASADMIN_JORAM_SERVERS);
                link.click();
                wr = wc.getFrameContents(FRAME_CONTENT);

                // Go to Local Server
                WebTable localTable = utils.getTable(wr, 1);
                link = localTable.getTableCell(0, 0).getLinks()[0];
                if (link == null) {
                    throw new IllegalStateException("No link was found to a local server in the 'Joram servers' page. ");
                }
                link.click();
                wr = wc.getFrameContents(FRAME_CONTENT);

                // Delete the created JMS Destination
                WebForm removeDestinationForm = wr.getForms()[0];
                SubmitButton button = removeDestinationForm.getSubmitButtons()[0];
                removeDestinationForm.setCheckbox("selectedItems", queueName, true);
                button.click();

                wr = wc.getFrameContents(FRAME_CONTENT);

                // Confirm
                link = wr.getFirstMatchingLink(WebLink.MATCH_URL_STRING, URL_JONASADMIN_JORAM_REMOVE);
                link.click();
                wr = wc.getFrameContents(FRAME_CONTENT);

                // Verify queue is deleted
                assertTrue("The '" + queueName + "' queue always exists. ", isQueue(queueName));

                // Verify console is updated
                assertTrue("The '" + queueName + "' queue was found in jonasAdmin after deleting. ", wr.getText().indexOf(queueName) == -1);
            }
        }

    }

    /**
     * Test a used topic
     * @throws Exception if error occurs
     *
     */
    public void testUsedTopic() throws Exception {


        WebResponse wr;
        WebLink link;
        WebTable table;
        String topicName = "mdbTopic";
        /*
         * To get some utils for WebTable
         */
        JonasAdminUtils utils = new JonasAdminUtils();

        // Disable errors of javascript
        HttpUnitOptions.setExceptionsThrownOnScriptError(false);
        // Disable exception thrown on error status
        HttpUnitOptions.setExceptionsThrownOnErrorStatus(false);
        if (jProp.isResource()) {
            // Joram platform is in jonas
            //if (isRarLoaded("joram_for_jonas_ra")) {
            if (isJoramRar()) {
                // Create a topic
                createTopic(topicName, getLocalServerId());

                // Use samplemdb.jar
                useBeans("samplemdb");

                // Go to Joram Platform
                wr = wc.getFrameContents(FRAME_TREE);
                link = wr.getFirstMatchingLink(WebLink.MATCH_URL_STRING, URL_JONASADMIN_JORAM);
                link.click();
                wr = wc.getFrameContents(FRAME_CONTENT);

                // Go to Joram Servers
                link = wr.getFirstMatchingLink(WebLink.MATCH_URL_STRING, URL_JONASADMIN_JORAM_SERVERS);
                link.click();
                wr = wc.getFrameContents(FRAME_CONTENT);

                // Go to Local Server
                WebTable localTable = utils.getTable(wr, 1);
                link = localTable.getTableCell(0, 0).getLinks()[0];
                if (link == null) {
                    throw new IllegalStateException("No link was found to a local server in the 'Joram servers' page. ");
                }
                link.click();
                wr = wc.getFrameContents(FRAME_CONTENT);

                // Verify there is no checkbox for mdbTopic
                table = utils.getTable(wr, 3);
                int topicRow = utils.getRow(topicName, table, 1).intValue();
                if (topicRow == -1) {
                    fail("'" + topicName + "' was not found in the destination list. ");
                }
                TableCell cell = table.getTableCell(topicRow, 0);
                assertEquals("There is an element for the '" + topicName + "'. ", 0, cell.getElementNames().length); // if there is a checkbox, the number of element is 1

                // Go to topic
                link = table.getTableCell(topicRow, 1).getLinks()[0];
                link.click();
                wr = wc.getFrameContents(FRAME_CONTENT);

                // Go to 'Used By' tab
                link = wr.getFirstMatchingLink(WebLink.MATCH_URL_STRING, URL_JONASADMIN_TOPIC_USED_BY);
                if (link == null) {
                    fail("There is no 'Used By' tab. ");
                }
                link.click();
                wr = wc.getFrameContents(FRAME_CONTENT);

                // Verify there is the Mdb MessageDrivenBean
                table = utils.getTable(wr, 0);
                int mdbRow = utils.getRow("Mdb", table).intValue();
                if (mdbRow == -1) {
                    fail("The 'Mdb' EJB was not found in the list of '" + topicName + "' users. ");
                }
                // Verify the type
                assertEquals("In list of '" + topicName + "' users, the type of 'Mdb' is not a MessageDrivenBean", "MessageDrivenBean", table.getTableCell(mdbRow, 1).getText());

                // Click to go to the Mdb page
                link = table.getTableCell(mdbRow, 0).getLinks()[0];
                if (link == null) {
                    fail("There is no link for 'Mdb' in 'Used By' page. ");
                }
                link.click();
                wr = wc.getFrameContents(FRAME_CONTENT);

                // Verify the link goes to "Domain ( jonas ) > Server JOnAS ( jonas ) > Services > EJB Container > samplemdb.jar"
                /* This link is not present as the samplemdb.jar was not deployed with jonasAdmin sa the management
                 * tree is not refreshed
                TableCell contentTitleTomThumbCell = wr.getTables()[0].getTableCell(0, 0);
                assertTrue("The link of 'Mdb' in 'Used By' page is maybe wrong. ", contentTitleTomThumbCell.getText().endsWith("> Services > EJB Container > samplemdb.jar"));
                */

                // Verify the Tabs
                WebTable tabTable = utils.getTabTable(wr);
                /*
                for (int i = 0; i < tabTable.getColumnCount(); i++) {
                	System.out.println("* " + i + " -- " + tabTable.getTableCell(0, i).getText());
                }*/
                int mdbIndex = F_JonasAdminEjbContainer.getMdbTabIndex();
                testTabs(tabTable,
                		F_JonasAdminEjbContainer.getNumberOfTabsForMdb(),
                		mdbIndex,
                		"Problem in 'Mdb' tab.");
                int mdbTabIndex = (mdbIndex -1) * 2;
                assertEquals("The selected tab is not Mdb",
                		F_JonasAdminEjbContainer.getMdbTabText(),
                		tabTable.getTableCell(0, mdbTabIndex).getText());
            } else {

            	System.out.println("------joram jar not loaded");
            }
        }
    }

    /**
     * Topic exists
     * @param name the name of the topic
     * @return true if the topic exists, false else
     * @throws Exception if an error occurs
     */
    private boolean isTopic(String name) throws Exception {
        MBeanServerConnection server = getMBeanServer();
        ObjectName on = ObjectName.getInstance("joramClient:type=topic,name=" + name);

        return server.isRegistered(on);
    }

    /**
     * Queue exists
     * @param name the name of the queue
     * @return true if the queue exists, false else
     * @throws Exception if an errors occurs
     */
    private boolean isQueue(String name) throws Exception {
        MBeanServerConnection server = getMBeanServer();
        ObjectName on = ObjectName.getInstance("joramClient:type=queue,name=" + name);

        return server.isRegistered(on);
    }

    /**
     * Create a topic
     * @param wr the content frame in the 'New Destination' page
     * @param name the name of the topic
     * @throws Exception if an error occurs
     */
    private void createTopic(WebResponse wr, String name) throws Exception {
        createDestination(wr, name, "topic");
    }

    /**
     * Create a queue
     * @param wr the content frame in the 'New Destination' page
     * @param name the name of the queue
     * @throws Exception if an error occurs
     */
    private void createQueue(WebResponse wr, String name) throws Exception {
        createDestination(wr, name, "queue");
    }

    /**
     * Create a jms destination
     * @param wr the content frame in the 'New Destination' page
     * @param name the name of the destination
     * @param type the type of the destination ("topic" or "queue").
     * @throws Exception if an error occurs
     */
    private void createDestination(WebResponse wr, String name, String type) throws Exception {
        SubmitButton button;
        WebForm form = wr.getForms()[0];
        form.setParameter("type", type);
        form.setParameter("name", name);

        // Submit
        button = form.getSubmitButtons()[0];
        button.click();
    }

    /**
     * Get the local server id
     * @return id of the local server
     * @throws Exception if an errors occurs
     */
    private int getLocalServerId() throws Exception {
        MBeanServerConnection server = getMBeanServer();
        ObjectName on = ObjectName.getInstance("joramClient:type=JoramAdapter,*");
        ObjectName joramAdapterON = (ObjectName) server.queryNames(on, null).iterator().next();

        return ((Short) server.getAttribute(joramAdapterON, "ServerId")).intValue();
    }

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

}
