#include <stdio.h>
#include <string.h>
#include "ramjet.h"
#include "options.h"

// set the options to their default values and initialise the hash table
void opt_init(OPTIONS* opt, HASHTABLE* ht)
{
    opt->log = NULL;
    opt->c960 = 0;
    opt->om = OM_FULL;
    hash_init(ht);
}

// close the log file
static void opt_log_close(FILE** log)
{
    if(*log != NULL) {
        fclose(*log);
        *log = NULL;
    }
}

// close the log file, deallocate the hash table
void opt_free(OPTIONS* opt, HASHTABLE* ht)
{
    opt_log_close(&opt->log);
    hash_free(ht);
}

// UCI output mode labels
const char* const om_uci_val[] = {"None", "Basic", "PV", "Full"};

// read the options from the UCI string
void opt_scan_uci(char* uci, OPTIONS* opt, HASHTABLE* ht)
{
    char* token;
    OUTPUTMODE om;
    int mb;

    // scan the UCI string in search for supported options
    for(token = grab_token(&uci); token[0] != '\0'; token = grab_token(&uci))

        // log file
        if(!strcmp(token, LOG_UCI_NAME)) {
            opt_log_close(&opt->log);
            uci = after_token(&uci, "value");
            if(!strcmp(grab_token(&uci), "true")) {
                opt->log = fopen(LOG_FILE, "w");
                setbuf(opt->log, NULL);
            }

        // chess 960
        } else if(strcmp(token, C960_UCI_NAME) == 0) {
            uci = after_token(&uci, "value");
            opt->c960 = (strcmp(grab_token(&uci), "true"))? 0 : 1;

        // output mode
        } else if(!strcmp(token, OM_UCI_NAME)) {
            uci = after_token(&uci, "value");
            token = grab_token(&uci);
            for(om = OM_NONE; om <= OM_FULL; ++om)
                if(!strcmp(token, om_uci_val[om]))
                    opt->om = om;

        // hash table
        } else if(!strcmp(token, HT_UCI_NAME)) {
            uci = after_token(&uci, "value");
            sscanf(uci, "%d", &mb);
            hash_alloc_mb(ht, mb);
        }
}

// test the functions above
int opt_test()
{
    char uci[] = "setoption LogFile true value false OutputMode value Basic UCI_Chess960 value thru";
    OPTIONS opt;

    // "name LogFile value true hehehe"
    // " name OutputMode what? value Basic"
    // " name UCI_Chess960 value fake"

    opt_init(&opt, NULL);
    opt_scan_uci(uci, &opt, NULL);
    if(opt.log || opt.c960 || opt.om != OM_BASIC)
        return 1;

    return 0;
}
