/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You 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.commons.daemon.support;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import org.apache.commons.daemon.Daemon;
import org.apache.commons.daemon.DaemonContext;

/**
 * Implementation of the Daemon that allows running
 * standard applications as daemons.
 * The applications must have the mechanism to manage
 * the application lifecycle.
 *
 */
public class DaemonWrapper implements Daemon
{

    private final static String ARGS            = "args";
    private final static String START_CLASS     = "start";
    private final static String START_METHOD    = "start.method";
    private final static String STOP_CLASS      = "stop";
    private final static String STOP_METHOD     = "stop.method";
    private final static String STOP_ARGS       = "stop.args";
    private String              configFileName  = null;
    private final DaemonConfiguration config;

    private final Invoker             startup;
    private final Invoker             shutdown;

    public DaemonWrapper()
    {
        config   = new DaemonConfiguration();
        startup  = new Invoker();
        shutdown = new Invoker();
    }

    /**
     * Called from DaemonLoader on init stage.
     * <p>
     * Accepts the following configuration arguments:
     * <ul>
     * <li>-daemon-properties: - load DaemonConfiguration properties from the specified file to act as defaults</li>
     * <li>-start: set start class name</li>
     * <li>-start-method: set start method name</li>
     * <li>-stop: set stop class name</li>
     * <li>-stop-method: set stop method name</li>
     * <li>-stop-argument: set optional argument to stop method</li>
     * <li>Anything else is treated as a startup argument</li>
     * </ul>
     * <p>
     * The following "-daemon-properties" are recognized:
     * <ul>
     * <li>args (startup argument)</li>
     * <li>start</li>
     * <li>start.method</li>
     * <li>stop</li>
     * <li>stop.method</li>
     * <li>stop.args</li>
     * </ul>
     * These are used to set the corresponding item if it has not already been
     * set by the command arguments. <b>However, note that args and stop.args are
     * appended to any existing values.</b>
     */
    @Override
    public void init(final DaemonContext context)
        throws Exception
    {
        final String[] args = context.getArguments();

        if (args != null) {
            int i;
            // Parse our arguments and remove them
            // from the final argument array we are
            // passing to our child.
            for (i = 0; i < args.length; i++) {
                if (args[i].equals("--")) {
                    // Done with argument processing
                    break;
                }
                else if (args[i].equals("-daemon-properties")) {
                    if (++i == args.length) {
                        throw new IllegalArgumentException(args[i - 1]);
                    }
                    configFileName = args[i];
                }
                else if (args[i].equals("-start")) {
                    if (++i == args.length) {
                        throw new IllegalArgumentException(args[i - 1]);
                    }
                    startup.setClassName(args[i]);
                }
                else if (args[i].equals("-start-method")) {
                    if (++i == args.length) {
                        throw new IllegalArgumentException(args[i - 1]);
                    }
                    startup.setMethodName(args[i]);
                }
                else if (args[i].equals("-stop")) {
                    if (++i == args.length) {
                        throw new IllegalArgumentException(args[i - 1]);
                    }
                    shutdown.setClassName(args[i]);
                }
                else if (args[i].equals("-stop-method")) {
                    if (++i == args.length) {
                        throw new IllegalArgumentException(args[i - 1]);
                    }
                    shutdown.setMethodName(args[i]);
                }
                else if (args[i].equals("-stop-argument")) {
                    if (++i == args.length) {
                        throw new IllegalArgumentException(args[i - 1]);
                    }
                    final String[] aa = new String[1];
                    aa[0] = args[i];
                    shutdown.addArguments(aa);
                }
                else {
                    // This is not our option.
                    // Everything else will be forwarded to the main
                    break;
                }
            }
            if (args.length > i) {
                final String[] copy = new String[args.length - i];
                System.arraycopy(args, i, copy, 0, copy.length);
                startup.addArguments(copy);
            }
        }
        if (config.load(configFileName)) {
            // Setup params if not set via cmdline.
            startup.setClassName(config.getProperty(START_CLASS));
            startup.setMethodName(config.getProperty(START_METHOD));
            // Merge the config with command line arguments
            startup.addArguments(config.getPropertyArray(ARGS));

            shutdown.setClassName(config.getProperty(STOP_CLASS));
            shutdown.setMethodName(config.getProperty(STOP_METHOD));
            shutdown.addArguments(config.getPropertyArray(STOP_ARGS));
        }
        startup.validate();
        shutdown.validate();
    }

    /**
     */
    @Override
    public void start()
        throws Exception
    {
        startup.invoke();
    }

    /**
     */
    @Override
    public void stop()
        throws Exception
    {
        shutdown.invoke();
    }

    /**
     */
    @Override
    public void destroy()
    {
        // Nothing for the moment
        System.err.println("DaemonWrapper: instance " + this.hashCode() + " destroy");
    }

    // Internal class for wrapping the start/stop methods
    class Invoker
    {
        private String      name = null;
        private String      call = null;
        private String[]    args = null;
        private Method      inst = null;
        private Class<?>    main = null;

        protected Invoker()
        {
        }

        protected void setClassName(final String name)
        {
            if (this.name == null) {
                this.name = name;
            }
        }
        protected void setMethodName(final String name)
        {
            if (this.call == null) {
                this.call = name;
            }
        }
        protected void addArguments(final String[] args)
        {
            if (args != null) {
                final ArrayList<String> aa = new ArrayList<String>();
                if (this.args != null) {
                    aa.addAll(Arrays.asList(this.args));
                }
                aa.addAll(Arrays.asList(args));
                this.args = aa.toArray(new String[aa.size()]);
            }
        }

        protected void invoke()
            throws Exception
        {
            if (name.equals("System") && call.equals("exit")) {
                // Just call a System.exit()
                // The start method was probably installed
                // a shutdown hook.
                System.exit(0);
            }
            else {
                Object obj   = null;
                if ((inst.getModifiers() & Modifier.STATIC) == 0) {
                    // We only need object instance for non-static methods.
                    obj = main.getConstructor().newInstance();
                }
                final Object arg[] = new Object[1];

                arg[0] = args;
                inst.invoke(obj, arg);
            }
        }
        // Load the class using reflection
        protected void validate()
            throws Exception
        {
            /* Check the class name */
            if (name == null) {
                name = "System";
                call = "exit";
                return;
            }
            if (args == null) {
                args = new String[0];
            }
            if (call == null) {
                call = "main";
            }

            // Get the ClassLoader loading this class
            final ClassLoader cl = DaemonWrapper.class.getClassLoader();
            if (cl == null) {
                throw new NullPointerException("Cannot retrieve ClassLoader instance");
            }
            final Class<?>[] ca = new Class[1];
            ca[0]      = args.getClass();
            // Find the required class
            main = cl.loadClass(name);
            if (main == null) {
                throw new ClassNotFoundException(name);
            }
            // Find the required method.
            // NoSuchMethodException will be thrown if matching method
            // is not found.
            inst = main.getMethod(call, ca);
        }
    }
}
