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

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 com.meterware.httpunit.HttpUnitOptions;
import com.meterware.httpunit.WebConversation;
import com.meterware.httpunit.WebForm;
import com.meterware.httpunit.WebLink;
import com.meterware.httpunit.WebResponse;
import com.meterware.httpunit.WebTable;

/**
 * Class for testing ...
 * @author Paul Kemler
 *
 */
public class F_JonasAdminServiceMail extends JonasAdminTestCase {

    /**
     * URL of mail service
     */
    private static final String URL_JONASADMIN_MAIL_SERVICE = "EditMailService.do";

    /**
     * URL of Mail resource
     */
    private static final String URL_JONASADMIN_MAIL = "EditDeploy.do?type=mail";

    /**
     * URL of Mail resource viewTree
     */
    private static final String URL_JONASADMIN_VIEW_MAIL = "viewTree.do?tree=domain*jonas*resources";

    /**
     * URL of Session Mail Factories
     */
    private static final String URL_JONASADMIN_SESSION_MF = "ListSessionMailFactories.do";

    /**
     * URL of Mime part datasource Mail Factories
     */
    private static final String URL_JONASADMIN_MIME_PART_DATASOURCE_MF = "ListMimePartMailFactories.do";

    /**
     * number of tabs when you are in the mail tabs
     */
    private static final int NUMBER_OF_TABS_FOR_MAIL = 3;

    /**
     * number of tabs when you are in the Session Mail Factory tab
     */
    private static final int NUMBER_OF_TABS_FOR_SESSION = 4;

    /**
     * number of tabs when you are in the MimePartDS Mail Factory tab
     */
    private static final int NUMBER_OF_TABS_FOR_MIME_PART_DS = 4;

    /**
     * Constructor with a specified name
     * @param s name
     */
    public F_JonasAdminServiceMail(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_JonasAdminServiceMail(testtorun));
        }
    }

    /**
     * Get a new TestSuite for this class
     * @return a new TestSuite for this class
     */
    public static TestSuite suite() {
        return new TestSuite(F_JonasAdminServiceMail.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 mail service without mail factory
     * @throws Exception if error occurs
     *
     */
    public void testNoDeployedMailFactory() throws Exception {

        WebResponse wr;
        WebLink link;
        WebTable table;
        WebTable tabTable;
        int selectedTab;
        /*
         * 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.isMail()) {

            // Undeploy mail factories
            undeployMailFactories(wc);

            // Go to mail service
            wr = wc.getFrameContents(FRAME_TREE);
            link = wr.getFirstMatchingLink( WebLink.MATCH_URL_STRING, URL_JONASADMIN_MAIL_SERVICE);
            link.click();
            wr = wc.getFrameContents(FRAME_CONTENT);
            selectedTab = 1;

            // Verify numbers
            table = utils.getTable(wr, 1);
            int sessionMF = Integer.parseInt(table.getTableCell(0, 2).getText());
            int mimePartDatasourceMF = Integer.parseInt(table.getTableCell(1, 2).getText());
            int total = Integer.parseInt(table.getTableCell(2, 2).getText());

            // Session factories    0
            assertEquals("The number of Session Factories is not '0'. ", 0, sessionMF);
            // MimePartDataSource   0
            assertEquals("The number of MimePartDataSource is not '0'. ", 0, mimePartDatasourceMF);
            // total = sessionMF + mimePartDatasourceMF
            assertEquals("The total is not the sum of Session factories and MimePartDataSource. ", sessionMF + mimePartDatasourceMF, total);

            // Verify tabs
            tabTable = utils.getTabTable(wr);
            testTabs(tabTable, NUMBER_OF_TABS_FOR_MAIL, selectedTab, "Problem in 'Mail' tab.");
            // - links
            assertTrue("The link " + URL_JONASADMIN_SESSION_MF + " is not found in the second tab. ",
                    tabTable.getTableCell(0, 2).getLinks()[0].getURLString().endsWith(URL_JONASADMIN_SESSION_MF));
            assertTrue("The link " + URL_JONASADMIN_MIME_PART_DATASOURCE_MF + " is not found in the third tab. ",
                    tabTable.getTableCell(0, 4).getLinks()[0].getURLString().endsWith(URL_JONASADMIN_MIME_PART_DATASOURCE_MF));


            // Go to Session factories
            link = wr.getFirstMatchingLink( WebLink.MATCH_URL_STRING, URL_JONASADMIN_SESSION_MF);
            link.click();
            wr = wc.getFrameContents(FRAME_CONTENT);

            // Verify tree
            WebResponse tree = wc.getFrameContents(FRAME_TREE);
            assertTrue("The node 'Session Factories' is not found in the tree. ", tree.getText().indexOf("Session Factories") != -1);

            // Verify Message : "No Session mail factories !"
            table = utils.getTable(wr, 0);
            assertEquals("There is not 1 row in the 'Session Mail Factories' table. ", 1, table.getRowCount());

            String messageNoSessionMF = "No Session mail factories !";
            assertEquals("There is not the expected message: '" + messageNoSessionMF + "'. ", messageNoSessionMF, table.getTableCell(0, 0).getText());

            // Verify tabs
            tabTable = utils.getTabTable(wr);
            testTabs(tabTable, NUMBER_OF_TABS_FOR_MAIL, selectedTab, "Problem in 'Session Mail Factories' tab.");
            // - links
            assertTrue("The link " + URL_JONASADMIN_MAIL_SERVICE + " is not found in the first tab. ",
                    tabTable.getTableCell(0, 0).getLinks()[0].getURLString().endsWith(URL_JONASADMIN_MAIL_SERVICE));
            assertTrue("The link " + URL_JONASADMIN_MIME_PART_DATASOURCE_MF + " is not found in the third tab. ",
                    tabTable.getTableCell(0, 4).getLinks()[0].getURLString().endsWith(URL_JONASADMIN_MIME_PART_DATASOURCE_MF));


            // Go to MimePartDataSource Mail Factories
            link = wr.getFirstMatchingLink( WebLink.MATCH_URL_STRING, URL_JONASADMIN_MIME_PART_DATASOURCE_MF);
            link.click();
            wr = wc.getFrameContents(FRAME_CONTENT);

            // Verify Message : "No MimePartDataSource mail factories !"
            table = utils.getTable(wr, 0);
            assertEquals("There is not 1 row in the 'Session Mail Factories' table. ", 1, table.getRowCount());

            String messageNoMimePartMF = "No MimePartDataSource mail factories !";
            assertEquals("There is not the expected message: '" + messageNoMimePartMF + "'. ", messageNoMimePartMF, table.getTableCell(0, 0).getText());

            // Verify tabs
            tabTable = utils.getTabTable(wr);
            testTabs(tabTable, NUMBER_OF_TABS_FOR_MAIL, selectedTab, "Problem in 'MimePartDataSource Mail Factories' tab.");
            // - links
            assertTrue("The link " + URL_JONASADMIN_MAIL_SERVICE + " is not found in the first tab. ",
                    tabTable.getTableCell(0, 0).getLinks()[0].getURLString().endsWith(URL_JONASADMIN_MAIL_SERVICE));
            assertTrue("The link " + URL_JONASADMIN_SESSION_MF + " is not found in the second tab. ",
                    tabTable.getTableCell(0, 2).getLinks()[0].getURLString().endsWith(URL_JONASADMIN_SESSION_MF));

        }

    }

    /**
     * Test mail service with mail factories
     * @throws Exception if error occurs
     *
     */
    public void testDeployedMailFactory() throws Exception {

        WebResponse wr;
        WebLink link;
        WebTable table;
        WebTable tabTable;
        int selectedTab;
        /*
         * 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.isMail()) {

            // Deploy mail factories
            deployMailFactories(wc);

            // Go to mail service
            wr = wc.getFrameContents(FRAME_TREE);
            link = wr.getFirstMatchingLink( WebLink.MATCH_URL_STRING, URL_JONASADMIN_MAIL_SERVICE);
            link.click();
            wr = wc.getFrameContents(FRAME_CONTENT);
            selectedTab = 1;

            // Verify numbers
            table = utils.getTable(wr, 1);
            int sessionMF = Integer.parseInt(table.getTableCell(0, 2).getText());
            int mimePartDatasourceMF = Integer.parseInt(table.getTableCell(1, 2).getText());
            int total = Integer.parseInt(table.getTableCell(2, 2).getText());

            // Session factories    > 0
            assertTrue("The number of Session Factories is not positif. ", sessionMF > 0);
            // MimePartDataSource   > 0
            assertTrue("The number of MimePartDataSource is not positif. ", mimePartDatasourceMF > 0);
            // total = sessionMF + mimePartDatasourceMF
            assertEquals("The total is not the sum of Session factories and MimePartDataSource. ", sessionMF + mimePartDatasourceMF, total);

            // Verify tabs
            tabTable = utils.getTabTable(wr);
            testTabs(tabTable, NUMBER_OF_TABS_FOR_MAIL, selectedTab, "Problem in 'Mail' tab.");
            // - links
            assertTrue("The link " + URL_JONASADMIN_SESSION_MF + " is not found in the second tab. ",
                    tabTable.getTableCell(0, 2).getLinks()[0].getURLString().endsWith(URL_JONASADMIN_SESSION_MF));
            assertTrue("The link " + URL_JONASADMIN_MIME_PART_DATASOURCE_MF + " is not found in the third tab. ",
                    tabTable.getTableCell(0, 4).getLinks()[0].getURLString().endsWith(URL_JONASADMIN_MIME_PART_DATASOURCE_MF));


            // Go to Session factories
            link = wr.getFirstMatchingLink( WebLink.MATCH_URL_STRING, URL_JONASADMIN_SESSION_MF);
            link.click();
            wr = wc.getFrameContents(FRAME_CONTENT);

            // Verify tree
            WebResponse tree = wc.getFrameContents(FRAME_TREE);
            assertTrue("The node 'Session Factories' is not found in the tree. ", tree.getText().indexOf("Session Factories") != -1);

            // Verify Session mail factories table
            table = utils.getTable(wr, 0);
            assertTrue("There are not more than 1 row in the 'Session Mail Factories' table. ", 1 < table.getRowCount());
            int rowMailSession = utils.getFirstRow("mailSession_1", table, 0).intValue();
            if (rowMailSession == -1) {
                throw new IllegalStateException("'mailSession_1' is not found in the table. ");
            }
            // JNDI name    mailSession_1
            assertEquals("It is not the JNDI name of 'mailSession_1'. ", "mailSession_1", table.getTableCell(rowMailSession, 1).getText());

            // Verify tabs
            tabTable = utils.getTabTable(wr);
            testTabs(tabTable, NUMBER_OF_TABS_FOR_MAIL, selectedTab, "Problem in 'Session Mail Factories' tab.");
            // - links
            assertTrue("The link " + URL_JONASADMIN_MAIL_SERVICE + " is not found in the first tab. ",
                    tabTable.getTableCell(0, 0).getLinks()[0].getURLString().endsWith(URL_JONASADMIN_MAIL_SERVICE));
            assertTrue("The link " + URL_JONASADMIN_MIME_PART_DATASOURCE_MF + " is not found in the third tab. ",
                    tabTable.getTableCell(0, 4).getLinks()[0].getURLString().endsWith(URL_JONASADMIN_MIME_PART_DATASOURCE_MF));

            // Go to url of the link
            link = table.getTableCell(rowMailSession, 0).getLinks()[0];
            link.click();
            wr = wc.getFrameContents(FRAME_CONTENT);

            // Verify tree
            tree = wc.getFrameContents(FRAME_TREE);
            assertTrue("The node 'mailSession_1' is not found in the tree.", tree.getText().indexOf("mailSession_1") != -1);

            // Verify number of tables
            try {
                table = utils.getTable(wr, 9);
            } catch (Exception e) {
                fail("There are not enough tables in 'mailSession_1' page.");
            }
            try {
                table = utils.getTable(wr, 10);
                fail("There are not too tables in 'mailSession_1' page.");
            } catch (Exception e) {
                // ok
            }

            // Type     Session
            table = utils.getTable(wr, 1);
            assertEquals("It is not the expected type of 'mailSession_1'. ", "Session", table.getTableCell(0, 2).getText());

            // Verify tabs
            tabTable = utils.getTabTable(wr);
            testTabs(tabTable, NUMBER_OF_TABS_FOR_SESSION, selectedTab, "Problem in 'mailSession_1' tab.");
            // - links
            assertTrue("The link " + URL_JONASADMIN_MAIL_SERVICE + " is not found in the first tab. ",
                    tabTable.getTableCell(0, 0).getLinks()[0].getURLString().endsWith(URL_JONASADMIN_MAIL_SERVICE));
            assertTrue("The link " + URL_JONASADMIN_SESSION_MF + " is not found in the second tab. ",
                    tabTable.getTableCell(0, 2).getLinks()[0].getURLString().endsWith(URL_JONASADMIN_SESSION_MF));
            assertTrue("The link " + URL_JONASADMIN_MIME_PART_DATASOURCE_MF + " is not found in the fourth tab. ",
                    tabTable.getTableCell(0, 6).getLinks()[0].getURLString().endsWith(URL_JONASADMIN_MIME_PART_DATASOURCE_MF));


            // Go to MimePartDataSource Mail Factories
            link = wr.getFirstMatchingLink( WebLink.MATCH_URL_STRING, URL_JONASADMIN_MIME_PART_DATASOURCE_MF);
            link.click();
            wr = wc.getFrameContents(FRAME_CONTENT);

            // Verify MimePartDatasource mail factories table
            table = utils.getTable(wr, 0);
            assertTrue("There are not more than 1 row in the 'MimePartDatasource Mail Factories' table. ", 1 < table.getRowCount());
            int rowMailMime = utils.getFirstRow("mailMimePartDS_1", table, 0).intValue();
            if (rowMailMime == -1) {
                throw new IllegalStateException("'mailMimePartDS_1' is not found in the table. ");
            }
            // JNDI name    mailMimePartDS_1
            assertEquals("It is not the JNDI name of 'mailMimePartDS_1'. ", "mailMimePartDS_1", table.getTableCell(rowMailMime, 1).getText());

            // Verify tabs
            tabTable = utils.getTabTable(wr);
            testTabs(tabTable, NUMBER_OF_TABS_FOR_MAIL, selectedTab, "Problem in 'MimePartDataSource Mail Factories' tab.");
            // - links
            assertTrue("The link " + URL_JONASADMIN_MAIL_SERVICE + " is not found in the first tab. ",
                    tabTable.getTableCell(0, 0).getLinks()[0].getURLString().endsWith(URL_JONASADMIN_MAIL_SERVICE));
            assertTrue("The link " + URL_JONASADMIN_SESSION_MF + " is not found in the second tab. ",
                    tabTable.getTableCell(0, 2).getLinks()[0].getURLString().endsWith(URL_JONASADMIN_SESSION_MF));

            // Go to url of the link
            link = table.getTableCell(rowMailMime, 0).getLinks()[0];
            link.click();
            wr = wc.getFrameContents(FRAME_CONTENT);

            // Verify tree
            tree = wc.getFrameContents(FRAME_TREE);
            assertTrue("The node 'mailMimePartDS_1' is not found in the tree.", tree.getText().indexOf("mailMimePartDS_1") != -1);

            // Verify number of tables
            try {
                table = utils.getTable(wr, 12);
            } catch (Exception e) {
                fail("There are not enough tables in 'mailMimePartDS_1' page.");
            }
            try {
                table = utils.getTable(wr, 13);
                fail("There are not too tables in 'mailMimePartDS_1' page.");
            } catch (Exception e) {
                // ok
            }

            // Type     MimePartDataSource
            table = utils.getTable(wr, 1);
            assertEquals("It is not the expected type of 'mailMimePartDS_1'. ", "MimePartDataSource", table.getTableCell(0, 2).getText());

            // Verify tabs
            tabTable = utils.getTabTable(wr);
            testTabs(tabTable, NUMBER_OF_TABS_FOR_MIME_PART_DS, selectedTab, "Problem in 'mailMimePartDS_1' tab.");
            // - links
            assertTrue("The link " + URL_JONASADMIN_MAIL_SERVICE + " is not found in the first tab. ",
                    tabTable.getTableCell(0, 0).getLinks()[0].getURLString().endsWith(URL_JONASADMIN_MAIL_SERVICE));
            assertTrue("The link " + URL_JONASADMIN_SESSION_MF + " is not found in the second tab. ",
                    tabTable.getTableCell(0, 2).getLinks()[0].getURLString().endsWith(URL_JONASADMIN_SESSION_MF));
            assertTrue("The link " + URL_JONASADMIN_MIME_PART_DATASOURCE_MF + " is not found in the fourth tab. ",
                    tabTable.getTableCell(0, 4).getLinks()[0].getURLString().endsWith(URL_JONASADMIN_MIME_PART_DATASOURCE_MF));

        }

    }


    /**
     * Undeploy all mail factories
     * @param wc The jonasAdmin connexion
     * @throws Exception if an error occurs
     */
    private void undeployMailFactories(WebConversation wc) throws Exception {
        WebLink link = null;

        // Go to Mail
        WebResponse wr = wc.getFrameContents(FRAME_TREE);
        link = wr.getFirstMatchingLink( WebLink.MATCH_URL_STRING, URL_JONASADMIN_MAIL);
        if (link != null) {
            link.click();
            wr = wc.getFrameContents(FRAME_CONTENT);
        } else {
            // branch is not opened
            link = wr.getFirstMatchingLink( WebLink.MATCH_URL_STRING, URL_JONASADMIN_VIEW_MAIL);
            if (link != null) {
                link.click();
                wr = wc.getFrameContents(FRAME_TREE);
                link = wr.getFirstMatchingLink( WebLink.MATCH_URL_STRING, URL_JONASADMIN_MAIL);
                if (link == null) {
                    throw new IllegalStateException("The link " + URL_JONASADMIN_MAIL + " is not found in tree. ");
                }
                link.click();
                wr = wc.getFrameContents(FRAME_CONTENT);
            } else {
                throw new IllegalStateException("The link " + URL_JONASADMIN_MAIL + " is not found in tree. ");
            }
        }

        // Undeploy all Mail Factories
        WebForm[] webForms = wr.getForms();
        WebForm webForm = webForms[0];

        String params = webForm.getParameterValue("deploy");
        WebForm.Scriptable script = webForm.getScriptableObject();

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

        script.setParameterValue("undeploy", params);

        WebResponse submitUndeploy = webForm.submit();

        webForms = submitUndeploy.getForms();
        webForm = webForms[0];

        WebResponse endResp = webForm.submit();
    }


    /**
     * Deploy all mail factories
     * @param wc The jonasAdmin connexion
     * @throws Exception if an error occurs
     */
    private void deployMailFactories(WebConversation wc) throws Exception {
        WebLink link = null;

        // Go to Mail
        WebResponse wr = wc.getFrameContents(FRAME_TREE);
        link = wr.getFirstMatchingLink( WebLink.MATCH_URL_STRING, URL_JONASADMIN_MAIL);
        if (link != null) {
            link.click();
            wr = wc.getFrameContents(FRAME_CONTENT);
        } else {
            // branch is not opened
            link = wr.getFirstMatchingLink( WebLink.MATCH_URL_STRING, URL_JONASADMIN_VIEW_MAIL);
            if (link != null) {
                link.click();
                wr = wc.getFrameContents(FRAME_TREE);
                link = wr.getFirstMatchingLink( WebLink.MATCH_URL_STRING, URL_JONASADMIN_MAIL);
                if (link == null) {
                    throw new IllegalStateException("The link " + URL_JONASADMIN_MAIL + " is not found in tree. ");
                }
                link.click();
                wr = wc.getFrameContents(FRAME_CONTENT);
            } else {
                throw new IllegalStateException("The link " + URL_JONASADMIN_MAIL + " is not found in tree. ");
            }
        }

        // Undeploy all Mail Factories
        WebForm[] webForms = wr.getForms();
        WebForm webForm = webForms[0];

        String params = webForm.getParameterValue("undeploy");
        WebForm.Scriptable script = webForm.getScriptableObject();

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

        script.setParameterValue("deploy", params);

        WebResponse submitUndeploy = webForm.submit();

        webForms = submitUndeploy.getForms();
        webForm = webForms[0];

        WebResponse endResp = webForm.submit();
    }

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

}
