/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkRTConf.h"
#include "SkOSFile.h"

SkRTConfRegistry::SkRTConfRegistry(): fConfs(100) {

    SkFILE *fp = sk_fopen(configFileLocation(), kRead_SkFILE_Flag);

    if (!fp) {
        return;
    }

    char line[1024];

    while (!sk_feof(fp)) {

        if (!sk_fgets(line, sizeof(line), fp)) {
            break;
        }

        char *commentptr = strchr(line, '#');
        if (commentptr == line) {
            continue;
        }
        if (commentptr) {
            *commentptr = '\0';
        }

        char sep[] = " \t\r\n";

        char *keyptr = strtok(line, sep);
        if (!keyptr) {
            continue;
        }

        char *valptr = strtok(NULL, sep);
        if (!valptr) {
            continue;
        }

        SkString* key = SkNEW_ARGS(SkString,(keyptr));
        SkString* val = SkNEW_ARGS(SkString,(valptr));

        fConfigFileKeys.append(1, &key);
        fConfigFileValues.append(1, &val);
    }
    sk_fclose(fp);
}

SkRTConfRegistry::~SkRTConfRegistry() {
    ConfMap::Iter iter(fConfs);
    SkTDArray<SkRTConfBase *> *confArray;

    while (iter.next(&confArray)) {
        delete confArray;
    }

    for (int i = 0 ; i < fConfigFileKeys.count() ; i++) {
        SkDELETE(fConfigFileKeys[i]);
        SkDELETE(fConfigFileValues[i]);
    }
}

const char *SkRTConfRegistry::configFileLocation() const {
    return "skia.conf"; // for now -- should probably do something fancier like home directories or whatever.
}

// dump all known runtime config options to the file with their default values.
// to trigger this, make a config file of zero size.
void SkRTConfRegistry::possiblyDumpFile() const {
    const char *path = configFileLocation();
    SkFILE *fp = sk_fopen(path, kRead_SkFILE_Flag);
    if (!fp) {
        return;
    }
    size_t configFileSize = sk_fgetsize(fp);
    if (configFileSize == 0) {
        printAll(path);
    }
    sk_fclose(fp);
}

// Run through every provided configuration option and print a warning if the user hasn't
// declared a correponding configuration object somewhere.
void SkRTConfRegistry::validate() const {
    for (int i = 0 ; i < fConfigFileKeys.count() ; i++) {
        if (!fConfs.find(fConfigFileKeys[i]->c_str())) {
            SkDebugf("WARNING: You have config value %s in your configuration file, but I've never heard of that.\n", fConfigFileKeys[i]->c_str());
        }
    }
}

void SkRTConfRegistry::printAll(const char *fname) const {
    SkWStream *o;

    if (fname) {
        o = new SkFILEWStream(fname);
    } else {
        o = new SkDebugWStream();
    }

    ConfMap::Iter iter(fConfs);
    SkTDArray<SkRTConfBase *> *confArray;

    while (iter.next(&confArray)) {
        if (confArray->getAt(0)->isDefault()) {
            o->writeText("# ");
        }
        confArray->getAt(0)->print(o);
        o->newline();
    }

    delete o;
}

bool SkRTConfRegistry::hasNonDefault() const {
    ConfMap::Iter iter(fConfs);
    SkTDArray<SkRTConfBase *> *confArray;
    while (iter.next(&confArray)) {
        if (!confArray->getAt(0)->isDefault()) {
            return true;
        }
    }
    return false;
}

void SkRTConfRegistry::printNonDefault(const char *fname) const {
    SkWStream *o;

    if (fname) {
        o = new SkFILEWStream(fname);
    } else {
        o = new SkDebugWStream();
    }
    ConfMap::Iter iter(fConfs);
    SkTDArray<SkRTConfBase *> *confArray;

    while (iter.next(&confArray)) {
        if (!confArray->getAt(0)->isDefault()) {
            confArray->getAt(0)->print(o);
            o->newline();
        }
    }

    delete o;
}

// register a configuration variable after its value has been set by the parser.
// we maintain a vector of these things instead of just a single one because the
// user might set the value after initialization time and we need to have
// all the pointers lying around, not just one.
void SkRTConfRegistry::registerConf(SkRTConfBase *conf) {
    SkTDArray<SkRTConfBase *> *confArray;
    if (fConfs.find(conf->getName(), &confArray)) {
        if (!conf->equals(confArray->getAt(0))) {
            SkDebugf("WARNING: Skia config \"%s\" was registered more than once in incompatible ways.\n", conf->getName());
        } else {
            confArray->append(1, &conf);
        }
    } else {
        confArray = new SkTDArray<SkRTConfBase *>;
        confArray->append(1, &conf);
        fConfs.set(conf->getName(),confArray);
    }
}

template <typename T> T doParse(const char *, bool *success ) {
    SkDebugf("WARNING: Invoked non-specialized doParse function...\n");
    if (success) {
        *success = false;
    }
    return (T) 0;
}

template<> bool doParse<bool>(const char *s, bool *success) {
    if (success) {
        *success = true;
    }
    if (!strcmp(s,"1") || !strcmp(s,"true")) {
        return true;
    }
    if (!strcmp(s,"0") || !strcmp(s,"false")) {
        return false;
    }
    if (success) {
        *success = false;
    }
    return false;
}

template<> const char * doParse<const char *>(const char * s, bool *success) {
    if (success) {
        *success = true;
    }
    return s;
}

template<> int doParse<int>(const char * s, bool *success) {
    if (success) {
        *success = true;
    }
    return atoi(s);
}

template<> unsigned int doParse<unsigned int>(const char * s, bool *success) {
    if (success) {
        *success = true;
    }
    return (unsigned int) atoi(s);
}

template<> float doParse<float>(const char * s, bool *success) {
    if (success) {
        *success = true;
    }
    return (float) atof(s);
}

template<> double doParse<double>(const char * s, bool *success) {
    if (success) {
        *success = true;
    }
    return atof(s);
}

static inline void str_replace(char *s, char search, char replace) {
    for (char *ptr = s ; *ptr ; ptr++) {
        if (*ptr == search) {
            *ptr = replace;
        }
    }
}

template<typename T> bool SkRTConfRegistry::parse(const char *name, T* value) {
    const char *str = NULL;

    for (int i = fConfigFileKeys.count() - 1 ; i >= 0; i--) {
        if (fConfigFileKeys[i]->equals(name)) {
            str = fConfigFileValues[i]->c_str();
            break;
        }
    }

    SkString environment_variable("skia.");
    environment_variable.append(name);

    const char *environment_value = getenv(environment_variable.c_str());
    if (environment_value) {
        str = environment_value;
    } else {
        // apparently my shell doesn't let me have environment variables that
        // have periods in them, so also let the user substitute underscores.
        SkAutoTMalloc<char> underscore_name(SkStrDup(environment_variable.c_str()));
        str_replace(underscore_name.get(), '.', '_');
        environment_value = getenv(underscore_name.get());
        if (environment_value) {
            str = environment_value;
        }
    }

    if (!str) {
        return false;
    }

    bool success;
    T new_value = doParse<T>(str, &success);
    if (success) {
        *value = new_value;
    } else {
        SkDebugf("WARNING: Couldn't parse value \'%s\' for variable \'%s\'\n",
                 str, name);
    }
    return success;
}

// need to explicitly instantiate the parsing function for every config type we might have...

template bool SkRTConfRegistry::parse(const char *name, bool *value);
template bool SkRTConfRegistry::parse(const char *name, int *value);
template bool SkRTConfRegistry::parse(const char *name, unsigned int *value);
template bool SkRTConfRegistry::parse(const char *name, float *value);
template bool SkRTConfRegistry::parse(const char *name, double *value);
template bool SkRTConfRegistry::parse(const char *name, const char **value);

template <typename T> void SkRTConfRegistry::set(const char *name,
                                                 T value,
                                                 bool warnIfNotFound) {
    SkTDArray<SkRTConfBase *> *confArray;
    if (!fConfs.find(name, &confArray)) {
        if (warnIfNotFound) {
            SkDebugf("WARNING: Attempting to set configuration value \"%s\","
                     " but I've never heard of that.\n", name);
        }
        return;
    }
    SkASSERT(confArray != NULL);
    for (SkRTConfBase **confBase = confArray->begin(); confBase != confArray->end(); confBase++) {
        // static_cast here is okay because there's only one kind of child class.
        SkRTConf<T> *concrete = static_cast<SkRTConf<T> *>(*confBase);

        if (concrete) {
            concrete->set(value);
        }
    }
}

template void SkRTConfRegistry::set(const char *name, bool value, bool);
template void SkRTConfRegistry::set(const char *name, int value, bool);
template void SkRTConfRegistry::set(const char *name, unsigned int value, bool);
template void SkRTConfRegistry::set(const char *name, float value, bool);
template void SkRTConfRegistry::set(const char *name, double value, bool);
template void SkRTConfRegistry::set(const char *name, char * value, bool);

SkRTConfRegistry &skRTConfRegistry() {
    static SkRTConfRegistry r;
    return r;
}
