/*
 * 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.
 */
// DWB11: add removeCommand: https://www.osgi.org/bugzilla/show_bug.cgi?id=49
// DWB12: there is no API to list commands: https://www.osgi.org/bugzilla/show_bug.cgi?id=49
// DWB13: addCommand() fails to add static methods (if target is Class)
package aQute.shell.runtime;

import java.io.*;
import java.lang.reflect.*;
import java.util.*;

import org.osgi.service.command.*;
import org.osgi.service.threadio.*;

public class CommandShellImpl implements CommandProcessor {
    Set<Converter>             converters      = new HashSet<Converter>();
    protected ThreadIO         threadIO;
    public final static Object NO_SUCH_COMMAND = new Object();
    Map<String, Object>        commands        = new LinkedHashMap<String, Object>();

    public CommandShellImpl() {
        addCommand("shell", this, "addCommand" );
        addCommand("shell", this, "removeCommand" );    // derek
    }
    
    public CommandSession createSession(InputStream in, PrintStream out,
            PrintStream err) {

        return new CommandSessionImpl(this, in, out, err);
    }

    public void setThreadio(ThreadIO threadIO) {
        this.threadIO = threadIO;
    }

    public void setConverter(Converter c) {
        converters.add(c);
    }

    public void unsetConverter(Converter c) {
        converters.remove(c);
    }

    public Object get(String name) {
        name = name.toLowerCase();
        int n = name.indexOf(':');
        if (n < 0)
            return null;

        String function = name.substring(n);
        
        Object cmd = null;

        if (commands.containsKey(name)) {
            cmd = commands.get(name);
        } else {
            String scope = name.substring(0, n);
            if (scope.equals("*")) {
                for (Map.Entry<String, Object> entry : commands.entrySet()) {
                    if (entry.getKey().endsWith(function)) {
                        cmd = entry.getValue();
                        break;
                    }
                }
            }
            
            // XXX: derek.baum@paremus.com
            // there is no API to list commands
            // so override otherwise illegal name ":"
            if (cmd == null && name.equals(":")) {
                return Collections.unmodifiableSet(commands.keySet());
            }
        }
        
        if (cmd == null)
            return null;

        if (cmd instanceof Function)
            return cmd;
        else
            return new Command(cmd, function.substring(1));
    }

    public void addCommand(String scope, Object target) {
        // derek - fix target class
        Class<?> tc = (target instanceof Class) ? (Class<?>) target : target.getClass();
        addCommand(scope, target, tc);
    }

    public void addCommand(String scope, Object target, Class<?> functions) {
        if (target == null)
            return;

        String[] names = getFunctions(functions);
        for (String function : names) {
            addCommand(scope, target, function);
        }
    }

    public void addCommand(String scope, Object target, String function) {
        commands.put((scope + ":" + function).toLowerCase(), target);
    }
    
    // derek.baum@paremus.com: need removeCommand, so stopped bundles can clean up.
    public void removeCommand(String scope, String function) {
        String func = (scope + ":" + function).toLowerCase();
        commands.remove(func);
    }
    
    public void removeCommand(Object target) {
        for (Iterator<Object> i = commands.values().iterator(); i.hasNext();) {
            if (i.next() == target)
                i.remove();
        }
    }

    private String[] getFunctions(Class<?> target) {
        String[] functions;
        Set<String> list = new TreeSet<String>();
        Method methods[] = target.getMethods();
        for (Method m : methods) {
            if (m.getDeclaringClass().equals(Object.class))    // derek
                continue;
            list.add(m.getName());
            if (m.getName().startsWith("get")) {
                String s = m.getName().substring(3);
                if (s.length() > 0)
                    list.add(s.substring(0, 1).toLowerCase() + s.substring(1));
            }
        }
        
        functions = list.toArray(new String[list.size()]);
        return functions;
    }

    protected void put(String name, Object target) {
        commands.put(name, target);
    }

    public Object convert(Class<?> desiredType, Object in) {
        for ( Converter c : converters ) {
            try {
            Object converted = c.convert(desiredType, in);
            if ( converted != null)
                return converted;
            } catch( Exception e ) {
                e.printStackTrace();
            }
        }
        return null;
    }

}
