/*
 * 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.geronimo.gshell.commands.ssh;

import com.google.code.sshd.server.ShellFactory;
import jline.Completor;
import jline.History;
import org.apache.geronimo.gshell.command.Variables;
import org.apache.geronimo.gshell.commandline.CommandLineExecutor;
import org.apache.geronimo.gshell.console.Console;
import org.apache.geronimo.gshell.console.JLineConsole;
import org.apache.geronimo.gshell.console.completer.AggregateCompleter;
import org.apache.geronimo.gshell.io.Closer;
import org.apache.geronimo.gshell.io.IO;
import org.apache.geronimo.gshell.notification.ExitNotification;
import org.apache.geronimo.gshell.shell.ShellContext;
import org.apache.geronimo.gshell.shell.ShellContextHolder;
import org.apache.geronimo.gshell.registry.CommandResolver;
import org.apache.geronimo.gshell.application.Application;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;

/**
 * SSHD {@link ShellFactory} which provides access to GShell.
 *
 * @version $Rev$ $Date$
 */
public class ShellFactoryImpl
    implements ShellFactory
{
    private final Logger log = LoggerFactory.getLogger(getClass());

    private Application application;

    private Console.Prompter prompter;

    private CommandLineExecutor executor;

    private History history;

    private List<Completor> completers;

    private Console.ErrorHandler errorHandler;

    public Console.Prompter getPrompter() {
        return prompter;
    }

    public void setPrompter(final Console.Prompter prompter) {
        this.prompter = prompter;
    }

    public CommandLineExecutor getExecutor() {
        return executor;
    }

    public void setExecutor(final CommandLineExecutor executor) {
        this.executor = executor;
    }

    public History getHistory() {
        return history;
    }

    public void setHistory(final History history) {
        this.history = history;
    }

    public List<Completor> getCompleters() {
        return completers;
    }

    public void setCompleters(final List<Completor> completers) {
        this.completers = completers;
    }

    public Console.ErrorHandler getErrorHandler() {
        return errorHandler;
    }

    public void setErrorHandler(final Console.ErrorHandler errorHandler) {
        this.errorHandler = errorHandler;
    }

    public Application getApplication() {
        return application;
    }

    public void setApplication(Application application) {
        this.application = application;
    }

    public Shell createShell() {
        return new ShellImpl();
    }

    public class ShellImpl
        implements ShellFactory.DirectShell, org.apache.geronimo.gshell.shell.Shell, ShellContext, Runnable
    {
        private InputStream in;

        private OutputStream out;

        private OutputStream err;

        private ExitCallback callback;

        private IO io;

        private Variables variables;

        private boolean closed;

        public void setInputStream(final InputStream in) {
            this.in = in;
        }

        public void setOutputStream(final OutputStream out) {
            this.out = out;
        }

        public void setErrorStream(final OutputStream err) {
            this.err = err;
        }

        public void setExitCallback(ExitCallback callback) {
            this.callback = callback;
        }

        public void start(final Map<String,String> env) throws IOException {
            this.io = new IO(in, out, err, false);

            // Create variables, inheriting the application ones
            this.variables = new Variables(application.getVariables());
            // Set up additional env
            if (env != null) {
                for (Map.Entry<String,String> entry : env.entrySet()) {
                    this.variables.set(entry.getKey(), entry.getValue());
                }
            }
            this.variables.set("gshell.prompt", application.getModel().getBranding().getPrompt());
            this.variables.set(CommandResolver.GROUP, "/");
            this.variables.set("gshell.username", env.get("USER"));
            this.variables.set("gshell.hostname", application.getLocalHost());
            // HACK: Add history for the 'history' command, since its not part of the Shell intf it can't really access it
            this.variables.set("gshell.internal.history", getHistory(), true);
            new Thread(this).start();
        }

        public void destroy() {
            close();
        }

        public ShellContext getContext() {
            return this;
        }

        public Object execute(final String line) throws Exception {

            return executor.execute(getContext(), line);
        }

        public Object execute(final String command, final Object[] args) throws Exception {
            return executor.execute(getContext(), args);
        }

        public Object execute(final Object... args) throws Exception {
            return executor.execute(getContext(), args);
        }

        public boolean isOpened() {
            return !closed;
        }

        public void close() {
            closed = true;
            Closer.close(in, out, err);
            callback.onExit(0);
        }

        public boolean isInteractive() {
            return false;
        }

        public void run(final Object... args) throws Exception {
            Console.Executor executor = new Console.Executor()
            {
                public Result execute(final String line) throws Exception {
                    assert line != null;
                    try {
                        ShellImpl.this.execute(line);
                    }
                    catch (ExitNotification n) {
                        return Result.STOP;
                    }
                    return Result.CONTINUE;
                }
            };

            IO io = getContext().getIo();

            // Setup the console runner
            JLineConsole console = new JLineConsole(executor, io);
            console.setPrompter(getPrompter());
            console.setErrorHandler(getErrorHandler());
            console.setHistory(getHistory());

            if (completers != null) {
                // Have to use aggregate here to get the completion list to update properly
                console.addCompleter(new AggregateCompleter(completers));
            }
            
            console.run();
        }

        public org.apache.geronimo.gshell.shell.Shell getShell() {
            return this;
        }

        public IO getIo() {
            return io;
        }

        public Variables getVariables() {
            return variables;
        }

        public void run() {
            ShellContext ctx = ShellContextHolder.get(true);

            try {
                ShellContextHolder.set(getContext());
                run(new Object[0]);
            }
            catch (Exception e) {
                log.error("Unhandled failure: " + e, e);
            }
            finally {
                ShellContextHolder.set(ctx);
                close();
            }
        }
    }
}