#include "server/commands/SnuviCommands.h"
#include "server/snuviscript/Snuvi.h"

static Commands::Arguments commandArguments = Commands::Raw();

static void helpScript() {
    puts("/script start <script>");
    puts("/script term");
}

static void commandScript(const Commands::Arguments& args) {
    if(args.getLength() < 2) {
        helpScript();
    } else if(strcmp(args[1], "start") == 0) {
        if(args.getLength() < 3) {
            puts("/script start <script>");
            return;
        }
        Snuvi::start(args[2]);
    } else if(strcmp(args[1], "term") == 0) {
        Snuvi::termAll();
        puts("all scripts were terminated");
    } else {
        helpScript();
    }
}

static void getArguments(Script* sc) {
    int length = commandArguments.getLength();
    Pointer p;
    p.offset = 0;
    p.array = asAllocate(&sc->arrays, sizeof(Pointer), length);
    sPushPointer(sc, &p);
    SnuviArray* array = asGet(&sc->arrays, p.array);
    if(array == nullptr) {
        sError(sc, "cannot allocate string memory");
        return;
    }
    Pointer* texts = static_cast<Pointer*>(array->data);
    for(int i = 0; i < length; i++) {
        Pointer text = Snuvi::toString(sc, commandArguments[i]);
        memcpy(texts + i, &text, sizeof(Pointer));
    }
}

void SnuviCommands::init() {
    Commands::add("script", commandScript);

    DataType type = dtText();
    dtDereference(&type);
    Snuvi::initFunction("getArguments", type, getArguments);
    Snuvi::addFunction();
}

void SnuviCommands::callEvent(Commands::Arguments& args) {
    commandArguments = args;
    Snuvi::callEvent(Snuvi::Event::COMMAND);
}