/*
 * 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.wisdom.registry;

import org.apache.commons.vfs.FileContent;
import org.apache.commons.vfs.FileObject;
import org.apache.commons.vfs.FileSystemException;
import org.apache.geronimo.gshell.command.Command;
import org.apache.geronimo.gshell.command.CommandException;
import org.apache.geronimo.gshell.command.Variables;
import org.apache.geronimo.gshell.registry.CommandResolver;
import org.apache.geronimo.gshell.registry.NoSuchCommandException;
import org.apache.geronimo.gshell.spring.BeanContainer;
import org.apache.geronimo.gshell.spring.BeanContainerAware;
import org.apache.geronimo.gshell.vfs.FileSystemAccess;
import org.apache.geronimo.gshell.wisdom.command.AliasCommand;
import org.apache.geronimo.gshell.wisdom.command.GroupCommand;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

/**
 * {@link CommandResolver} component.
 *
 * @version $Rev$ $Date$
 */
public class CommandResolverImpl
    implements CommandResolver, BeanContainerAware
{
    private final Logger log = LoggerFactory.getLogger(getClass());

    private final FileSystemAccess fileSystemAccess;

    private final GroupDirectoryResolver groupDirResolver;

    private FileObject commandsRoot;

    private FileObject aliasesRoot;

    private BeanContainer container;

    public CommandResolverImpl(final FileSystemAccess fileSystemAccess, final GroupDirectoryResolver groupDirResolver) {
        assert fileSystemAccess != null;
        this.fileSystemAccess = fileSystemAccess;

        assert groupDirResolver != null;
        this.groupDirResolver = groupDirResolver;
    }

    public void setBeanContainer(final BeanContainer container) {
        assert container != null;

        this.container = container;
    }

    //
    // TODO: Consider adding an undefined command handler to allow for even more customization of
    //       execution when no defined command is found?  So one can say directly execute a
    //       *.gsh script, which under the covers will translate into 'source *.gsh' (or really
    //       should be 'shell *.gsh' once we have a sub-shell command.
    //

    public Command resolveCommand(final String name, final Variables variables) throws CommandException {
        assert name != null;
        assert variables != null;

        log.debug("Resolving command name: {}", name);

        // Always try to resolve aliases before we resolve commands
        Command command = resolveAliasCommand(name, variables);

        if (command == null) {
            try {
                FileObject file = resolveCommandFile(name, variables);

                if (file != null) {
                    command = createCommand(file);
                }
            }
            catch (FileSystemException e) {
                log.warn("Unable to resolve command for name: " + name, e);
            }
        }

        if (command == null) {
            throw new NoSuchCommandException(name);
        }
        
        log.debug("Resolved command: {}", command);

        return command;
    }

    private FileObject getAliasesRoot() throws FileSystemException {
        if (aliasesRoot == null) {
            aliasesRoot = fileSystemAccess.createVirtualFileSystem(ALIASES_ROOT);
        }

        return aliasesRoot;
    }

    private AliasCommand resolveAliasCommand(final String name, final Variables variables) {
        assert name != null;
        assert variables != null;

        log.trace("Resolving alias for name: {}", name);
        
        AliasCommand command = null;

        try {
            FileObject root = getAliasesRoot();
            FileObject file = root.resolveFile(name);

            if (file != null && file.exists()) {
                log.trace("Resolved file: {}", file);
                
                command = createAliasCommand(file);
            }
        }
        catch (FileSystemException e) {
            log.debug("Failed to resolve alias command for name: " + name, e);
        }

        return command;
    }

    private FileObject getCommandsRoot() throws FileSystemException {
        if (commandsRoot == null) {
            commandsRoot = fileSystemAccess.createVirtualFileSystem(COMMANDS_ROOT);
        }

        return commandsRoot;
    }

    private FileObject resolveCommandFile(final String name, final Variables variables) throws FileSystemException {
        assert name != null;
        assert variables != null;

        log.trace("Resolving command file: {}", name);

        FileObject root = getCommandsRoot();

        // Special handling for root & group
        if (name.equals("/")) {
            return root;
        }
        else if (name.equals(".")) {
            return groupDirResolver.getGroupDirectory(variables);
        }
        
        Collection<String> searchPath = getSearchPath(variables);

        log.trace("Search path: {}", searchPath);

        FileObject groupDir = groupDirResolver.getGroupDirectory(variables);

        log.trace("Group dir: {}", groupDir);

        FileObject file = null;

        for (String pathElement : searchPath) {
            log.trace("Resolving file; name={}, pathElement={}", name, pathElement);

            FileObject dir;
            
            if (pathElement.equals("/")) {
                dir = root;
            }
            else if (pathElement.startsWith("/")) {
                dir = fileSystemAccess.resolveFile(root, pathElement.substring(1, pathElement.length()));
            }
            else {
                dir = fileSystemAccess.resolveFile(groupDir, pathElement);
            }

            log.trace("Dir: {}", dir);

            FileObject tmp = fileSystemAccess.resolveFile(dir, name);

            log.trace("File: {}", tmp);

            if (tmp.exists()) {
                file = tmp;
                break;
            }
        }

        if (file != null) {
            log.trace("Resolved file: {}", file);
        }

        return file;
    }

    private Collection<String> getSearchPath(final Variables vars) {
        assert vars != null;

        Object tmp = vars.get(PATH);

        if (tmp instanceof String) {
            return Arrays.asList(((String)tmp).split(PATH_SEPARATOR));
        }
        else if (tmp != null) {
            log.error("Invalid type for variable '" + PATH + "'; expected String; found: " + tmp.getClass());
        }

        // Return the default search path (group then root)
        return Arrays.asList(".", "/");
    }

    public Collection<Command> resolveCommands(String name, Variables variables) throws CommandException {
        // name may be null
        assert variables != null;

        if (name == null) {
            name = "";
        }
        
        log.debug("Resolving commands for name: {}", name);

        List<Command> commands = new ArrayList<Command>();

        try {
            FileObject file = resolveCommandFile(name, variables);

            log.trace("Resolved (for commands): {}", file);

            if (file != null && file.exists()) {
                if (file.getType().hasChildren()) {
                    for (FileObject child : file.getChildren()) {
                        Command command = createCommand(child);
                        commands.add(command);
                    }
                }
                else {
                    Command command = createCommand(file);
                    commands.add(command);
                }
            }
        }
        catch (FileSystemException e) {
            log.warn("Failed to resolve commands for name: " + name, e);
        }

        log.debug("Resolved {} commands", commands.size());
        if (log.isTraceEnabled()) {
            for (Command command : commands) {
                log.trace("    {}", command);
            }
        }

        return commands;
    }

    private Command createCommand(FileObject file) throws FileSystemException, CommandException {
        assert file != null;

        // HACK: Must dereference to avoid problems with the DelegateFileObject impl
        file = fileSystemAccess.dereference(file);

        log.trace("Creating command for file: {} ({})", file, file.getClass());

        Command command = null;

        if (file.exists()) {
            FileContent content = file.getContent();
            command = (Command)content.getAttribute("COMMAND");

            if (command == null) {
                if (file.getType().hasChildren()) {
                    command = createGroupCommand(file);
                    content.setAttribute("COMMAND", command);
                }

                // TODO: Try to construct AliasCommand?
            }
        }

        if (command == null) {
            throw new CommandException("Unable to create command for file: " + file.getName());
        }

        return command;
    }

    private AliasCommand createAliasCommand(final FileObject file) throws FileSystemException {
        assert file != null;

        String name = file.getName().getBaseName();

        log.trace("Creating command for alias: {}", name);

        AliasCommand command = container.getBean(AliasCommand.class);

        String alias = (String) file.getContent().getAttribute("ALIAS");
        if (alias == null) {
            throw new IllegalStateException("Alias meta-file does not contain 'ALIAS' attribute: " + file);
        }

        command.setName(name);
        command.setAlias(alias);

        return command;
    }

    private GroupCommand createGroupCommand(final FileObject file) throws FileSystemException {
        assert file != null;

        log.trace("Creating command for group: {}", file);

        GroupCommand command = container.getBean(GroupCommand.class);
        command.setPath(file.getName().getBaseName());
        
        return command;
    }
}
