/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed 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.
 */

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "symtab.h"
#include "commands.h"

#if 1
#define TRACE(...)  printf(__VA_ARGS__)
#else
#define TRACE(...)  /**/
#endif

typedef enum {
    CMD_TYPE_UNKNOWN = -1,
    CMD_TYPE_COMMAND = 0,
    CMD_TYPE_FUNCTION
} CommandType;

typedef struct {
    const char *name;
    void *cookie;
    CommandType type;
    CommandArgumentType argType;
    CommandHook hook;
} CommandEntry;

static struct {
    SymbolTable *symbolTable;
    bool commandStateInitialized;
} gCommandState;

int
commandInit()
{
    if (gCommandState.commandStateInitialized) {
        return -1;
    }
    gCommandState.symbolTable = createSymbolTable();
    if (gCommandState.symbolTable == NULL) {
        return -1;
    }
    gCommandState.commandStateInitialized = true;
    return 0;
}

void
commandCleanup()
{
    if (gCommandState.commandStateInitialized) {
        gCommandState.commandStateInitialized = false;
        deleteSymbolTable(gCommandState.symbolTable);
        gCommandState.symbolTable = NULL;
//xxx need to free the entries and names in the symbol table
    }
}

static int
registerCommandInternal(const char *name, CommandType type,
        CommandArgumentType argType, CommandHook hook, void *cookie)
{
    CommandEntry *entry;

    if (!gCommandState.commandStateInitialized) {
        return -1;
    }
    if (name == NULL || hook == NULL) {
        return -1;
    }
    if (type != CMD_TYPE_COMMAND && type != CMD_TYPE_FUNCTION) {
        return -1;
    }
    if (argType != CMD_ARGS_BOOLEAN && argType != CMD_ARGS_WORDS) {
        return -1;
    }

    entry = (CommandEntry *)malloc(sizeof(CommandEntry));
    if (entry != NULL) {
        entry->name = strdup(name);
        if (entry->name != NULL) {
            int ret;

            entry->cookie = cookie;
            entry->type = type;
            entry->argType = argType;
            entry->hook = hook;
            ret = addToSymbolTable(gCommandState.symbolTable,
                        entry->name, entry->type, entry);
            if (ret == 0) {
                return 0;
            }
        }
        free(entry);
    }

    return -1;
}

int
registerCommand(const char *name,
        CommandArgumentType argType, CommandHook hook, void *cookie)
{
    return registerCommandInternal(name,
            CMD_TYPE_COMMAND, argType, hook, cookie);
}

int
registerFunction(const char *name, FunctionHook hook, void *cookie)
{
    return registerCommandInternal(name,
            CMD_TYPE_FUNCTION, CMD_ARGS_WORDS, (CommandHook)hook, cookie);
}

Command *
findCommand(const char *name)
{
    return (Command *)findInSymbolTable(gCommandState.symbolTable,
            name, CMD_TYPE_COMMAND);
}

Function *
findFunction(const char *name)
{
    return (Function *)findInSymbolTable(gCommandState.symbolTable,
            name, CMD_TYPE_FUNCTION);
}

CommandArgumentType
getCommandArgumentType(Command *cmd)
{
    CommandEntry *entry = (CommandEntry *)cmd;

    if (entry != NULL) {
        return entry->argType;
    }
    return CMD_ARGS_UNKNOWN;
}

static int
callCommandInternal(CommandEntry *entry, int argc, const char *argv[])
{
    if (entry != NULL && entry->argType == CMD_ARGS_WORDS &&
            (argc == 0 || (argc > 0 && argv != NULL)))
    {
        int i;
        for (i = 0; i < argc; i++) {
            if (argv[i] == NULL) {
                goto bail;
            }
        }
        TRACE("calling command %s\n", entry->name);
        return entry->hook(entry->name, entry->cookie, argc, argv);
    }
bail:
    return -1;
}

static int
callBooleanCommandInternal(CommandEntry *entry, bool arg)
{
    if (entry != NULL && entry->argType == CMD_ARGS_BOOLEAN) {
        TRACE("calling boolean command %s\n", entry->name);
        return entry->hook(entry->name, entry->cookie, arg ? 1 : 0, NULL);
    }
    return -1;
}

int
callCommand(Command *cmd, int argc, const char *argv[])
{
    return callCommandInternal((CommandEntry *)cmd, argc, argv);
}

int
callBooleanCommand(Command *cmd, bool arg)
{
    return callBooleanCommandInternal((CommandEntry *)cmd, arg);
}

int
callFunctionInternal(CommandEntry *entry, int argc, const char *argv[],
        char **result, size_t *resultLen)
{
    if (entry != NULL && entry->argType == CMD_ARGS_WORDS &&
            (argc == 0 || (argc > 0 && argv != NULL)))
    {
        if (result != NULL)
        {
            /* This is the actual invocation of the function,
             * which means that none of the arguments are allowed
             * to be NULL.
             */
            int i;
            for (i = 0; i < argc; i++) {
                if (argv[i] == NULL) {
                    goto bail;
                }
            }
            TRACE("calling function %s\n", entry->name);
            return ((FunctionHook)entry->hook)(entry->name, entry->cookie,
                    argc, argv, result, resultLen);
        }
    }
bail:
    return -1;
}

int
callFunction(Function *fn, int argc, const char *argv[],
        char **result, size_t *resultLen)
{
    return callFunctionInternal((CommandEntry *)fn, argc, argv,
            result, resultLen);
}
