/*
 * 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.felix.gogo.jline;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;

import org.apache.felix.gogo.jline.Shell.Context;
import org.apache.felix.gogo.jline.SingleServiceTracker.SingleServiceListener;
import org.apache.felix.gogo.runtime.Token;
import org.apache.felix.gogo.runtime.Tokenizer;
import org.apache.felix.service.command.CommandProcessor;
import org.apache.felix.service.command.CommandSession;
import org.apache.felix.service.command.Converter;
import org.jline.terminal.Terminal;
import org.jline.terminal.TerminalBuilder;
import org.osgi.annotation.bundle.Header;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceRegistration;

public class Activator implements BundleActivator, SingleServiceListener {
    private final Set<ServiceRegistration<?>> regs = new HashSet<>();
    private BundleContext context;
    private SingleServiceTracker<CommandProcessor> commandProcessorTracker;

    private Runnable closer;

    public Activator() {
    }

    public void start(BundleContext context) throws Exception {
        this.context = context;
        this.commandProcessorTracker = new SingleServiceTracker<>(context, CommandProcessor.class, this);
        this.commandProcessorTracker.open();
    }

    public void stop(BundleContext context) {
        Iterator<ServiceRegistration<?>> iterator = regs.iterator();
        while (iterator.hasNext()) {
            ServiceRegistration<?> reg = iterator.next();
            reg.unregister();
            iterator.remove();
        }
        this.commandProcessorTracker.close();
    }

    @Override
    public void serviceFound() {
        try {
            closer = startShell(context, commandProcessorTracker.getService());
        } catch (Exception e) {
            // Ignore
        }
    }

    @Override
    public void serviceLost() {
        stopShell();
    }

    @Override
    public void serviceReplaced() {
        serviceLost();
        serviceFound();
    }

    private Runnable startShell(BundleContext context, CommandProcessor processor) throws Exception {
        Dictionary<String, Object> dict = new Hashtable<>();
        dict.put(CommandProcessor.COMMAND_SCOPE, "gogo");

        // register converters
        regs.add(context.registerService(Converter.class.getName(), new Converters(context.getBundle(0).getBundleContext()), null));

        // register commands

        dict.put(CommandProcessor.COMMAND_FUNCTION, Builtin.functions);
        regs.add(context.registerService(Builtin.class.getName(), new Builtin(), dict));

        dict.put(CommandProcessor.COMMAND_FUNCTION, Procedural.functions);
        regs.add(context.registerService(Procedural.class.getName(), new Procedural(), dict));

        dict.put(CommandProcessor.COMMAND_FUNCTION, Posix.functions);
        regs.add(context.registerService(Posix.class.getName(), new Posix(processor), dict));

        Shell shell = new Shell(new ShellContext(), processor);
        dict.put(CommandProcessor.COMMAND_FUNCTION, Shell.functions);
        regs.add(context.registerService(Shell.class.getName(), shell, dict));

        Terminal terminal = TerminalBuilder.builder()
                .name("gogo")
                .system(true)
                .nativeSignals(true)
                .signalHandler(Terminal.SignalHandler.SIG_IGN)
                .build();
        CommandSession session = processor.createSession(terminal.input(), terminal.output(), terminal.output());
        AtomicBoolean closing = new AtomicBoolean();

        Thread thread = new Thread(() -> {
            String errorMessage = "gogo: unable to create console";
            try {
                session.put(Shell.VAR_TERMINAL, terminal);
                try {
                    List<String> args = new ArrayList<>();
                    args.add("--login");
                    String argstr = shell.getContext().getProperty("gosh.args");
                    if (argstr != null) {
                        Tokenizer tokenizer = new Tokenizer(argstr);
                        Token token;
                        while ((token = tokenizer.next()) != null) {
                            args.add(token.toString());
                        }
                    }
                    shell.gosh(session, args.toArray(new String[args.size()]));
                } catch (Throwable e) {
                    Object loc = session.get(".location");
                    if (null == loc || !loc.toString().contains(":")) {
                        loc = "gogo";
                    }
                    errorMessage = loc.toString();
                    throw e;
                }
            } catch (Throwable e) {
                if (!closing.get()) {
                    System.err.println(errorMessage + e.getClass().getSimpleName() + ": " + e.getMessage());
                    e.printStackTrace();
                }
            }
        }, "Gogo shell");
        // start shell on a separate thread...
        thread.start();

        return () -> {
            closing.set(true);
            shell.stop();
            try {
                terminal.close();
            } catch (IOException e) {
                // Ignore
            }
            try {
                long t0 = System.currentTimeMillis();
                while (thread.isAlive()) {
                    thread.interrupt();
                    thread.join(10);
                    if (System.currentTimeMillis() - t0 > 5000) {
                        System.err.println("!!! FAILED TO STOP EXECUTOR !!!");
                        break;
                    }
                }
            } catch (InterruptedException e) {
                // Restore administration...
                Thread.currentThread().interrupt();
            }
        };
    }

    private void stopShell() {
        if (closer != null) {
            closer.run();
        }
        while (!regs.isEmpty()) {
            ServiceRegistration<?> reg = regs.iterator().next();
            regs.remove(reg);
            reg.unregister();
        }
    }

    private class ShellContext implements Context {
        public String getProperty(String name) {
            return context.getProperty(name);
        }

        public void exit() throws Exception {
            context.getBundle(0).stop();
        }
    }
}