/*
 * Copyright (c) 2006, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package test.admin;

import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

import java.net.MalformedURLException;
import java.io.InputStream;
import java.io.IOException;

import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.testng.Assert;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Parameters;

import org.glassfish.external.amx.AMXGlassfish;
import org.glassfish.admin.amx.core.proxy.ProxyFactory;
import org.glassfish.admin.amx.base.DomainRoot;
import java.io.File;

/** The base class for admin console tests. Designed for extension.
 * @author jdlee@dev.java.net
 * @since GlassFish v3 Prelude
 */
public class BaseAdminConsoleTest {

    protected String adminUrl;
    private HttpClient client;
    private static final int AC_TEST_DELAY = 1000; // One second
    private static final int AC_TEST_ITERATIONS = 60; // One minute
    private String host;
    private int port;
    private volatile MBeanServerConnection mMBeanServerConnection;
    private volatile DomainRoot mDomainRoot;
    private static final String FILE_SEP = System.getProperty("file.separator");
    private static final String CONSOLE_DIR_PATH = FILE_SEP + "lib" + FILE_SEP + 
            "install" + FILE_SEP + "applications" + FILE_SEP + "__admingui";
    private static final String GLASSFISH_DIR = FILE_SEP + ".." + FILE_SEP +"glassfish";

    // Copied from Lloyd's AMX tests
    void setUpEnvironment(int port) {
        try {
            if (mMBeanServerConnection == null) {
                host = System.getProperty("http.host");
                this.port = port;

                mMBeanServerConnection = _getMBeanServerConnection();
                mDomainRoot = _getDomainRoot(mMBeanServerConnection);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * This BeforeTest method will verify that the login form is available.  Once
     * it is found, the login form is submitted.  If the login succeeds, then
     * the tests are allowed to continue.  If the login fails, the each test will
     * fail.
     * @param url
     * @throws java.lang.Exception
     */
    @BeforeTest
    @Parameters({"admin.console.url", "amx.rmiport"})
    public void loginBeforeTest(String url, int port) throws Exception {
        this.adminUrl = url;
        setUpEnvironment(port);
        client = new HttpClient();

        boolean formFound = false;
        int iteration = 0;
        if (!checkForAdminConsoleDirectory()) {
            Assert.fail("The admin console directory was not found at " +
                this.getDomainRoot().getInstallDir() + GLASSFISH_DIR + CONSOLE_DIR_PATH +
                ".  Please check your installation.");
        }

        while (!formFound && iteration < AC_TEST_ITERATIONS) {
            iteration++;

            formFound = getUrlAndTestForStrings(adminUrl + "login.jsf","id=\"Login.username\"");
            if (!formFound) {
                System.err.println("***** Login page not found.  Sleeping to allow app to deploy (" +
                        iteration + " of " + AC_TEST_ITERATIONS + ")...");
                Thread.sleep(AC_TEST_DELAY);
            }
        }

        if (!formFound) {
            Assert.fail("The login form was not found.");
        }

        // The login for was found, so let's now POST the form to authenticate our session.
        PostMethod post = new PostMethod(adminUrl + "j_security_check");
        post.setRequestBody(new NameValuePair[]{
                    new NameValuePair("j_username", "admin"), new NameValuePair("j_password", "")
                });
        post.getParams().setCookiePolicy(CookiePolicy.RFC_2109);

        int statusCode = client.executeMethod(post);
        if (statusCode == 302) {
            Header locationHeader = post.getResponseHeader("location");
            if (locationHeader != null) {
                Assert.assertTrue(locationHeader.getValue().startsWith(this.adminUrl));
            } else {
                Assert.fail("Failed to login: no redirect header");
            }
        } else if (statusCode != HttpStatus.SC_OK) {
            Assert.fail("Login failed: " + post.getStatusLine() + ": " + statusCode);
        }
    }

    /**
     * This method uses the AMX API to get the install directory, then checks to
     * see if the admin console directory is present.
     * @return
     */
    protected boolean checkForAdminConsoleDirectory() {
        // Hard-coding "../glassfish" to help cover a deficiency in IPS
        File directory = new File(this.getDomainRoot().getInstallDir() + GLASSFISH_DIR + CONSOLE_DIR_PATH);
        return directory.exists();
    }

    @AfterTest
    public void shutdownClient() {
        client = null;
    }

    /**
     * This method will request the specified URL and examine the response for the
     * needle specified.
     * @param url
     * @param needle
     * @return
     * @throws java.lang.Exception
     */
    protected boolean getUrlAndTestForStrings(String url, String... needles) throws IOException {
        String haystack = getUrl(url);
        boolean allFound = true;
        for (String needle : needles) {
            if (haystack.indexOf(needle) == -1) {
                allFound = false;
            }
        }

        return allFound;
    }

    /**
     * Request the specified URL and return the contents as a String
     * @param url
     * @return
     * @throws java.io.IOException
     */
    protected String getUrl(String url) throws IOException {
        GetMethod get = new GetMethod(url);
        get.getParams().setCookiePolicy(CookiePolicy.RFC_2109);
        get.setFollowRedirects(true);

        int statusCode = client.executeMethod(get);
        //Also accepts SC_ACCPTED ie 202 for the case when the console is still loading.
        if ((statusCode != HttpStatus.SC_OK) && (statusCode != HttpStatus.SC_ACCEPTED)  ) {
            Assert.fail("BaseAdminConsoleTest.getUrlAndTestForString() failed.  HTTP Status Code:  " + statusCode);
        }
        String response = getString(get.getResponseBodyAsStream());
        get.releaseConnection();
        return response;
    }

    /**
     * Read the entire contents of the InputStream and return them as a String
     * @param in
     * @return
     * @throws java.io.IOException
     */
    protected String getString(InputStream in) throws IOException {
        StringBuilder out = new StringBuilder();
        byte[] b = new byte[4096];
        for (int n; (n = in.read(b)) != -1;) {
            out.append(new String(b, 0, n));
        }
        in.close();
        return out.toString();
    }

    /*
     * These methods were all copied from Lloyd's AMX QL tests.
     */

    protected DomainRoot getDomainRoot() {
        return mDomainRoot;
    }

    protected DomainRoot _getDomainRoot(final MBeanServerConnection conn)
            throws MalformedURLException, IOException, java.net.MalformedURLException {
        final ObjectName domainRootObjectName = AMXGlassfish.DEFAULT.bootAMX(conn);
        final DomainRoot domainRoot = ProxyFactory.getInstance(conn).getDomainRootProxy();
        return domainRoot;
    }

    private MBeanServerConnection _getMBeanServerConnection()
            throws MalformedURLException, IOException {
        // service:jmx:rmi:///jndi/rmi://192.168.1.8:8686/jmxrmi
        // service:jmx:jmxmp://localhost:8888
        // CHANGE to RMI once it's working
        //
        // final String urlStr = "service:jmx:jmxmp://" + mHost + ":" + mPort;
        final String urlStr = "service:jmx:rmi:///jndi/rmi://" + host + ":" + port + "/jmxrmi";

        final JMXServiceURL url = new JMXServiceURL(urlStr);

        final JMXConnector jmxConn = JMXConnectorFactory.connect(url);
        final MBeanServerConnection conn = jmxConn.getMBeanServerConnection();
        conn.getDomains();	// sanity check
        return conn;
    }
}

