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

import java.io.File;

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

/**
 * Class for testing security service
 * @author Paul Kemler
 *
 */
public class F_JonasAdminServiceSecurity extends JonasAdminTestCase {

    /**
     * URL of security service
     */
    private static final String URL_JONASADMIN_SECURITY = "EditServiceSecurity.do";

    /**
     * number of tabs when you are in security
     */
    private static final int NUMBER_OF_TABS_FOR_SECURITY = 1;

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

    /**
     * Get a new TestSuite for this class
     * @return a new TestSuite for this class
     */
    public static TestSuite suite() {
        return new TestSuite(F_JonasAdminServiceSecurity.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 realms table
     * @throws Exception if error occurs
     *
     */
    public void testRealms() throws Exception {

        WebResponse wr;
        WebLink link;
        WebTable table;
        WebTable tabTable;
        int selectedTab;
        String name;
        String type;
        String path;
        boolean used;
        JonasAdminUtils utils = new JonasAdminUtils();

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

        // Test only if the security service is enabled
        if (jProp.isSecurity()) {

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

            // Verify 'Realms'
            path = File.separator + "jonasAdmin";
            name = "memrlm_1";
            type = "memory";
            used = true;
            try {
                table = utils.getTable(wr, 0);
                int rowJonasAdmin = utils.getFirstRow(path, table, 2).intValue();
                if (rowJonasAdmin != -1) {
                    testRealmRow(table, rowJonasAdmin, name, type, path, used);
                }
            } catch (Exception e) {
                if (jProp.isCatalina()) {
                    fail("The realm security table is not found. ");
                } else {
                    throw new IllegalStateException("Not implemented: JETTY. ");
                }
            }

            // "Olstore": type=datasource and not used
            if (jProp.isEar()) {
                useEar("olstore");

                path = File.separator + "olstore";
                name = "olstorerlm_1";
                type = "datasource";
                used = false;
                wr = wc.getFrameContents(FRAME_TREE);
                link = wr.getFirstMatchingLink( WebLink.MATCH_URL_STRING, URL_JONASADMIN_SECURITY);
                link.click();
                wr = wc.getFrameContents(FRAME_CONTENT);
                table = utils.getTable(wr, 0);
                int rowDatasourceType = utils.getFirstRow(path, table, 2).intValue();
                if (rowDatasourceType != -1) {
                    testRealmRow(table, rowDatasourceType, name, type, path, used);
                } else {
                    if (jProp.isCatalina()) {
                        fail("The realm security for the context path '" + path + "' is not found. ");
                    } else {
                        throw new IllegalStateException("Not implemented: JETTY. ");
                    }
                }
            }


            // Verify there is 1 tab
            tabTable = utils.getTabTable(wr);
            testTabs(tabTable, NUMBER_OF_TABS_FOR_SECURITY, selectedTab, "Problem in 'Realms' tab.");
        }
    }

    /**
     * Test infos of a realm row
     * @param table the table of realms
     * @param row the row to test
     * @param name the value of the name
     * @param type the value of the type
     * @param path the value of the path
     * @param used the value of 'used'
     */
    private void testRealmRow(WebTable table, int row, String name, String type, String path, boolean used) {
        // Verify Name
        assertEquals("It is not the name for the context path '" + path + "' . ", name, table.getTableCell(row, 0).getText());
        // Verify Type
        assertEquals("It is not the type for the context path '" + path + "' . ", type, table.getTableCell(row, 1).getText());
        // Verify Used
        if (used) {
            assertEquals("It is not the value of 'used' for the context path '" + path + "' . ", used, table.getTableCell(row, 3).getImages()[0].getSource().endsWith("images/icon/tag_blue.gif"));
        } else {
            assertEquals("It is not the value of 'used' for the context path '" + path + "' . ", 0, table.getTableCell(row, 3).getImages().length);
        }
    }

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

}
