#include <cstdio>
#include "XLIFFFile.h"
#include "ValuesFile.h"
#include "localize.h"

int pseudolocalize_xliff(XLIFFFile* xliff, bool expand);

static int
test_filename(const string& file, const string& locale, const string& expected)
{
    string result = translated_file_name(file, locale);
    if (result != expected) {
        fprintf(stderr, "translated_file_name test failed\n");
        fprintf(stderr, "  locale='%s'\n", locale.c_str());
        fprintf(stderr, "  expected='%s'\n", expected.c_str());
        fprintf(stderr, "    result='%s'\n", result.c_str());
        return 1;
    } else {
        if (false) {
            fprintf(stderr, "translated_file_name test passed\n");
            fprintf(stderr, "  locale='%s'\n", locale.c_str());
            fprintf(stderr, "  expected='%s'\n", expected.c_str());
            fprintf(stderr, "    result='%s'\n", result.c_str());
        }
        return 0;
    }
}

static int
translated_file_name_test()
{
    bool all = true;
    int err = 0;

    if (all) err |= test_filename("//device/samples/NotePad/res/values/strings.xml", "zz_ZZ",
                                  "//device/samples/NotePad/res/values-zz-rZZ/strings.xml");

    if (all) err |= test_filename("//device/samples/NotePad/res/values/strings.xml", "zz",
                                  "//device/samples/NotePad/res/values-zz/strings.xml");

    if (all) err |= test_filename("//device/samples/NotePad/res/values/strings.xml", "",
                                  "//device/samples/NotePad/res/values/strings.xml");

    return err;
}

bool
return_false(const string&, const TransUnit& unit, void* cookie)
{
    return false;
}

static int
delete_trans_units()
{
    XLIFFFile* xliff = XLIFFFile::Parse("testdata/strip_xliff.xliff");
    if (xliff == NULL) {
        printf("couldn't read file\n");
        return 1;
    }
    if (false) {
        printf("XLIFF was [[%s]]\n", xliff->ToString().c_str());
    }

    xliff->Filter(return_false, NULL);

    if (false) {
        printf("XLIFF is [[%s]]\n", xliff->ToString().c_str());

        set<StringResource> const& strings = xliff->GetStringResources();
        printf("strings.size=%zd\n", strings.size());
        for (set<StringResource>::iterator it=strings.begin(); it!=strings.end(); it++) {
            const StringResource& str = *it;
            printf("STRING!!! id=%s value='%s' pos=%s file=%s version=%d(%s)\n", str.id.c_str(),
                    str.value->ContentsToString(ANDROID_NAMESPACES).c_str(),
                    str.pos.ToString().c_str(), str.file.c_str(), str.version,
                    str.versionString.c_str());
        }
    }
 
    return 0;
}

static int
filter_trans_units()
{
    XLIFFFile* xliff = XLIFFFile::Parse("testdata/strip_xliff.xliff");
    if (xliff == NULL) {
        printf("couldn't read file\n");
        return 1;
    }

    if (false) {
        printf("XLIFF was [[%s]]\n", xliff->ToString().c_str());
    }

    Settings setting;
    xliff->Filter(keep_this_trans_unit, &setting);

    if (false) {
        printf("XLIFF is [[%s]]\n", xliff->ToString().c_str());

        set<StringResource> const& strings = xliff->GetStringResources();
        printf("strings.size=%zd\n", strings.size());
        for (set<StringResource>::iterator it=strings.begin(); it!=strings.end(); it++) {
            const StringResource& str = *it;
            printf("STRING!!! id=%s value='%s' pos=%s file=%s version=%d(%s)\n", str.id.c_str(),
                    str.value->ContentsToString(ANDROID_NAMESPACES).c_str(),
                    str.pos.ToString().c_str(), str.file.c_str(), str.version,
                    str.versionString.c_str());
        }
    }
 
    return 0;
}

static int
settings_test()
{
    int err;
    map<string,Settings> settings;
    map<string,Settings>::iterator it;

    err = read_settings("testdata/config.xml", &settings, "//asdf");
    if (err != 0) {
        return err;
    }

    if (false) {
        for (it=settings.begin(); it!=settings.end(); it++) {
            const Settings& setting = it->second;
            printf("CONFIG:\n");
            printf("              id='%s'\n", setting.id.c_str());
            printf("      oldVersion='%s'\n", setting.oldVersion.c_str());
            printf("  currentVersion='%s'\n", setting.currentVersion.c_str());
            int i=0;
            for (vector<string>::const_iterator app=setting.apps.begin();
                    app!=setting.apps.end(); app++) {
                printf("        apps[%02d]='%s'\n", i, app->c_str());
                i++;
            }
            i=0;
            for (vector<Reject>::const_iterator reject=setting.reject.begin();
                    reject!=setting.reject.end(); reject++) {
                i++;
                printf("      reject[%02d]=('%s','%s','%s')\n", i, reject->file.c_str(),
                        reject->name.c_str(), reject->comment.c_str());
            }
        }
    }

    for (it=settings.begin(); it!=settings.end(); it++) {
        const Settings& setting = it->second;
        if (it->first != setting.id) {
            fprintf(stderr, "it->first='%s' setting.id='%s'\n", it->first.c_str(),
                    setting.id.c_str());
            err |= 1;
        }
    }


    return err;
}

static int
test_one_pseudo(bool big, const char* expected)
{
    XLIFFFile* xliff = XLIFFFile::Parse("testdata/pseudo.xliff");
    if (xliff == NULL) {
        printf("couldn't read file\n");
        return 1;
    }
    if (false) {
        printf("XLIFF was [[%s]]\n", xliff->ToString().c_str());
    }

    pseudolocalize_xliff(xliff, big);
    string newString = xliff->ToString();
    delete xliff;

    if (false) {
        printf("XLIFF is [[%s]]\n", newString.c_str());
    }

    if (false && newString != expected) {
        fprintf(stderr, "xliff didn't translate as expected\n");
        fprintf(stderr, "newString=[[%s]]\n", newString.c_str());
        fprintf(stderr, "expected=[[%s]]\n", expected);
        return 1;
    }

    return 0;
}

static int
pseudolocalize_test()
{
    int err = 0;
    
    err |= test_one_pseudo(false, "");
    //err |= test_one_pseudo(true, "");

    return err;
}

int
localize_test()
{
    bool all = true;
    int err = 0;

    if (all) err |= translated_file_name_test();
    if (all) err |= delete_trans_units();
    if (all) err |= filter_trans_units();
    if (all) err |= settings_test();
    if (all) err |= pseudolocalize_test();

    return err;
}

