/*
 * @author <a href="mailto:novotny@aei.mpg.de">Jason Novotny</a>
 * @version $Id$
 */
package org.gridlab.gridsphere.services.core.registry.impl.tomcat;

import org.gridlab.gridsphere.portlet.PortletRequest;
import org.gridlab.gridsphere.services.core.registry.impl.PortletManager;
import org.gridlab.gridsphere.services.core.registry.PortletManagerService;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.methods.GetMethod;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

public class TomcatManagerWrapper {

    private static String USERNAME = "gridsphere";
    private static String PASSWORD = "gridsphere";

    private static TomcatManagerWrapper instance = new TomcatManagerWrapper();
    private PortletManagerService pm = PortletManager.getInstance();

    private TomcatManagerWrapper() {
    }

    public static TomcatManagerWrapper getInstance() {
        return instance;
    }

    public static final void setCredentials(String name, String password) {
        USERNAME = name;
        PASSWORD = password;
    }

    public TomcatWebAppResult doCommand(PortletRequest req, String command) throws TomcatManagerException {
        TomcatWebAppResult result = null;
        try {
            String serverName = req.getServerName();
            int serverPort = req.getServerPort();


            HttpClient client = new HttpClient();
            client.getState().setCredentials(
                    null,
                    serverName,
                    new UsernamePasswordCredentials(USERNAME, PASSWORD)
            );

            GetMethod get = new GetMethod("http://" + serverName + ":" + serverPort + "/manager" + command);

            get.setDoAuthentication( true );

            // execute the GET
            int status = client.executeMethod( get );

            BufferedReader reader = new BufferedReader(new InputStreamReader(get.getResponseBodyAsStream()));
            // get first line
            // should be something like:
            // OK - some information text
            String line = null;

            line = reader.readLine();
            StringTokenizer tokenizer = new StringTokenizer(line, "-");
            if (tokenizer.countTokens() == 2) {
                String rc = tokenizer.nextToken();
                String description = tokenizer.nextToken();
                result = new TomcatWebAppResult(rc, description);
            }

            while ((line = reader.readLine()) != null) {
                result.addWebAppDescriptor(line);
            }
            reader.close();

            // release any connection resources used by the method
            get.releaseConnection();


        } catch (IOException e) {
            throw new TomcatManagerException("Unable to perform command: ", e);
        }
        return result;
    }

    /**
     * Return the list of ui applications.
     */
    public TomcatWebAppResult getWebAppList(PortletRequest req) throws TomcatManagerException {
        return doCommand(req, "/list");
    }

    public List getPortletAppList(PortletRequest req) throws TomcatManagerException {
        List webapps = pm.getPortletWebApplicationNames();
        List l = new ArrayList();
        TomcatWebAppResult result = doCommand(req, "/list");
        if (result != null) {

            Iterator it = result.getWebAppDescriptions().iterator();
            while (it.hasNext()) {
                TomcatWebAppDescription webAppDesc = (TomcatWebAppDescription) it.next();
                //System.err.println(webAppDesc.toString());
                if (webapps.contains((webAppDesc.getContextPath()))) {
                    String desc = pm.getPortletWebApplicationDescription(webAppDesc.getContextPath());
                    webAppDesc.setDescription(desc);
                    l.add(webAppDesc);
                }
            }
        }
        return l;
    }

    public List getNonPortletAppList(PortletRequest req) throws TomcatManagerException {
        List webapps = pm.getPortletWebApplicationNames();
        List l = new ArrayList();
        TomcatWebAppResult result = doCommand(req, "/list");
        if (result != null) {
            Iterator it = result.getWebAppDescriptions().iterator();
            while (it.hasNext()) {
                TomcatWebAppDescription webAppDesc = (TomcatWebAppDescription) it.next();
                //System.err.println(webAppDesc.toString());
                if (!webapps.contains((webAppDesc.getContextPath()))) {
                    //String desc = pm.getPortletWebApplicationDescription(webAppDesc.getContextPath());
                    //webAppDesc.setDescription("");
                    l.add(webAppDesc);
                }
            }
        }
        return l;
    }

    public TomcatWebAppResult reloadWebApp(PortletRequest req, String context) throws TomcatManagerException {
        if (!context.startsWith("/")) context = "/" + context;
        return doCommand(req, "/reload?path=" + context);
    }

    public TomcatWebAppResult removeWebApp(PortletRequest req, String context) throws TomcatManagerException {
        if (!context.startsWith("/")) context = "/" + context;
        return doCommand(req, "/remove?path=" + context);
    }

    public TomcatWebAppResult startWebApp(PortletRequest req, String context) throws TomcatManagerException {
        if (!context.startsWith("/")) context = "/" + context;
        return doCommand(req, "/start?path=" + context);
    }

    public TomcatWebAppResult stopWebApp(PortletRequest req, String context) throws TomcatManagerException {
        if (!context.startsWith("/")) context = "/" + context;
        return doCommand(req, "/stop?path=" + context);
    }

    public TomcatWebAppResult deployWebApp(PortletRequest req, String context) throws TomcatManagerException {
        if (!context.startsWith("/")) context = "/" + context;
        return doCommand(req, "/deploy?path=" + context);
    }

    public TomcatWebAppResult undeployWebApp(PortletRequest req, String context) throws TomcatManagerException {
        if (!context.startsWith("/")) context = "/" + context;
        return doCommand(req, "/undeploy?path=" + context);
    }

    public TomcatWebAppResult installWebApp(PortletRequest req, String context, String warFile) throws TomcatManagerException {
        //install?path=/foo&war=file:/path/to/foo
        if (!context.startsWith("/")) context = "/" + context;
        http://localhost:8080/manager/deploy?war=foo

	    return doCommand(req, "/deploy?war=" + warFile);

        //return doCommand(req, "/install?path=" + context + "&war=" + warFile);
    }

    public TomcatWebAppResult installWebApp(PortletRequest req, String warFile) throws TomcatManagerException {
        //install?path=/foo&war=file:/path/to/foo
        return doCommand(req, "/install?war=" + warFile);
    }
}

@@ -200,24 +200,130 @@
 letRequest;%0A
+import org.gridlab.gridsphere.portlet.PortletLog;%0Aimport org.gridlab.gridsphere.portlet.impl.SportletLog;%0A
 import org.g
@@ -380,24 +380,24 @@
 letManager;%0A
-
 import org.g
@@ -1121,24 +1121,113 @@
 tInstance();
+%0A    private static PortletLog log = SportletLog.getInstance(TomcatManagerWrapper.class);
 %0A%0A    privat
@@ -1697,24 +1697,69 @@
 rverName();%0A
+            String scheme = req.getScheme();%0A
             
@@ -2056,43 +2056,34 @@
     
-GetMethod get = new GetMethod(%22http
+String cmdStr = scheme + %22
 ://%22
@@ -2137,19 +2137,122 @@
  command
-)
 ;%0A
+            GetMethod get = new GetMethod(cmdStr);%0A            log.debug(%22connecting to URL %22 + cmdStr);
 %0A       

add some debugging