/*
 * $Header: /home/cvspublic/jakarta-slide/proposals/tamino/src/store/org/apache/slide/store/tamino/tools/config/Config.java,v 1.2 2004/09/27 15:48:18 pnever Exp $
 * $Revision: 1.2 $
 * $Date: 2004/09/27 15:48:18 $
 *
 * ====================================================================
 *
 * Copyright 1999-2004 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.slide.store.tamino.tools.config;

import java.io.File;
import java.io.IOException;
import java.util.List;
import org.apache.slide.store.tamino.tools.Command;
import org.apache.slide.store.tamino.tools.Tws;
import org.apache.slide.store.tamino.tools.config.HelpSecurity;
import org.apache.slide.store.tamino.tools.config.InstallSecurity;
import org.apache.slide.store.tamino.tools.config.Security;
import org.apache.slide.util.XAssertionFailed;
import org.apache.slide.util.XException;
import org.apache.slide.util.cli.Abort;
import org.apache.slide.util.cli.Actuals;
import org.apache.slide.util.cli.CommandLine;
import org.apache.slide.util.os.Catalina;

public class Config extends Tws {
    private static final String ARG_MODULE = "module";
    private static final String ARG_APACHE_HOME = "apachehome";
    
    private static final String ARG_ADMINISTRATOR = "administrator";
    private static final String ARG_PASSWD = "password";
    private static final String ARG_DOMAIN = "domain";
    private static final String ARG_TYPE = "type";
    
    private static final String CMD_INSTALL = "install";
    private static final String CMD_REMOVE = "remove";
    private static final String CMD_HELP = "helpsecurity";
    
    private static final String MODULE_APACHE = "apache";
    private static final String MODULE_SERVICE = "service";
    private static final String MODULE_SECURIRTY = "security";
    
    public Config() {
        super(new String[] { CMD_INSTALL, CMD_REMOVE, CMD_HELP }, "config",
              "Configures security, services and web server integration.",
              new String[] {
                    "Installs or removes the Tamino WebDAV server module specified by the first option." },
              "Commands:\n" +
                  "  helpsecurity         Prints help about security options.\n" +
                  "  install              Installs the specified module.\n" +
                  "  remove               Removes the specified module.\n" +
                  "Modules:\n" +
                  "  security             URM security module.\n" +
                  "  service              Service (Windows only).\n" +
                  "  apache               Apache 2 web server integration.\n" +
                  "Options security:\n" +
                  "  [-type ...]          the security type to be installed\n" +
                  "  [-administrator ...] name of the administrator. Default: administrator\n" +
                  "  [-password ...]      password of the administrator. Default: administrator\n" +
                  "  [-domain ...]        domain of the administrator. Default: none\n" +
                  "Options apache:\n" +
                  "  [-apachehome ...]    Apache home directory. Mandatory.\n" +
                  "Examples:\n" +
                  "  inodavconfig install apache -apachehome c:\\apache2\n" +
                  "  inodavconfig remove service"
             );
    }
    
    public CommandLine commandLine() {
        CommandLine cl;
        
        cl = new CommandLine(true);
        cl.addLiteral(ARG_MODULE, MODULE_APACHE);
        cl.addLiteral(ARG_MODULE, MODULE_SERVICE);
        cl.addLiteral(ARG_MODULE, MODULE_SECURIRTY);
        
        cl.addOption(ARG_ADMINISTRATOR);
        cl.addOption(ARG_PASSWD);
        cl.addOption(ARG_DOMAIN);
        cl.addOption(ARG_TYPE);
        cl.addOption(ARG_APACHE_HOME);
        
        return cl;
    }
    
    public Command dispatch(String cmd, Actuals actuals) throws Abort {
        String module;
        boolean install;
        List additionals;
        
        additionals = actuals.getAdditionals();
        if (cmd.equals(CMD_HELP)) {
            return new HelpSecurity("help security", out, additionals.isEmpty()? null : (String) additionals.get(0), getCatalina().home);
        }
        module = actuals.getString(ARG_MODULE);
        if (CMD_INSTALL.equals(cmd)) {
            install = true;
        } else if (CMD_REMOVE.equals(cmd)) {
            install = false;
        } else {
            throw new XAssertionFailed(cmd);
        }
        if (additionals.size() > 0 && !MODULE_SECURIRTY.equals(module)) {
            throw new Abort("undefined action: " + additionals.get(0));
        }
        if (MODULE_APACHE.equals(module)) {
            return apache(actuals, install);
        } else if (MODULE_SERVICE.equals(module)) {
            return service(install);
        } else if (MODULE_SECURIRTY.equals(module)) {
            return security(actuals, additionals, install);
        } else {
            if (module == null) {
                throw new Abort("missing module option");
            } else {
                throw new Abort("unkown module: " + module);
            }
        }
    }
    
    private Command security(Actuals actuals, final List additionals, boolean install) throws Abort {
        final String namespace = getNamespace();
        
        if (install) {
            final Catalina catalina = getCatalina();
            final String admin = actuals.getString(ARG_ADMINISTRATOR, "administrator");
            final String passwd = actuals.getString(ARG_PASSWD, admin);
            final String type = actuals.getString(ARG_TYPE, null);
            final String domain = actuals.getString(ARG_DOMAIN, null);
            if (type == null) {
                throw new Abort("missing type argument");
            }
            return new InstallSecurity(out, namespace, type, catalina.home, additionals, admin, passwd, domain);
        } else {
            if (additionals.size() > 0) {
                throw new Abort("undefined action: " + additionals.get(0));
            }
            return new Command("remove security", out) {
                public void run() throws XException {
                    Security.remove(namespace);
                }
            };
        }
    }
    
    private Command apache(Actuals actuals, final boolean install) throws Abort {
        String apacheHome;
        final Apache apache;
        final Catalina catalina;
        
        apacheHome = actuals.getString(ARG_APACHE_HOME);
        if (apacheHome == null) {
            throw new Abort("mandatory argument missing: " + ARG_APACHE_HOME);
        }
        apache = new Apache(new File(apacheHome));
        catalina = getCatalina();
        if (install) {
            return new Command("install apache", out) {
                public void run() throws Abort, IOException, XException {
                    if (apache.install(catalina)) {
                        out.normal.println("overwriting existing configuration");
                    }
                }
            };
        } else {
            return new Command("remove apache", out) {
                public void run() throws Abort, IOException {
                    apache.remove(catalina);
                }
            };
        }
    }
    
    private Command service(final boolean install) throws Abort {
        final Service service = new Service();
        final Catalina catalina = getCatalina();
        
        if (install) {
            return new Command("install service", out) {
                public void run() throws Abort, IOException {
                    service.install(catalina);
                }
            };
        } else {
            return new Command("remove service", out) {
                public void run() throws Abort, IOException {
                    service.remove(catalina);
                }
            };
        }
    }
}


