/*
 * Copyright (C) 2009 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 <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <string>

#include "expr.h"
#include "parser.h"

extern int yyparse(Expr** root, int* error_count);

int expect(const char* expr_str, const char* expected, int* errors) {
    Expr* e;
    char* result;

    printf(".");

    int error_count = parse_string(expr_str, &e, &error_count);
    if (error_count > 0) {
        printf("error parsing \"%s\" (%d errors)\n",
               expr_str, error_count);
        ++*errors;
        return 0;
    }

    State state;
    state.cookie = NULL;
    state.script = strdup(expr_str);
    state.errmsg = NULL;

    result = Evaluate(&state, e);
    free(state.errmsg);
    free(state.script);
    if (result == NULL && expected != NULL) {
        printf("error evaluating \"%s\"\n", expr_str);
        ++*errors;
        return 0;
    }

    if (result == NULL && expected == NULL) {
        return 1;
    }

    if (strcmp(result, expected) != 0) {
        printf("evaluating \"%s\": expected \"%s\", got \"%s\"\n",
               expr_str, expected, result);
        ++*errors;
        free(result);
        return 0;
    }

    free(result);
    return 1;
}

int test() {
    int errors = 0;

    expect("a", "a", &errors);
    expect("\"a\"", "a", &errors);
    expect("\"\\x61\"", "a", &errors);
    expect("# this is a comment\n"
           "  a\n"
           "   \n",
           "a", &errors);


    // sequence operator
    expect("a; b; c", "c", &errors);

    // string concat operator
    expect("a + b", "ab", &errors);
    expect("a + \n \"b\"", "ab", &errors);
    expect("a + b +\nc\n", "abc", &errors);

    // string concat function
    expect("concat(a, b)", "ab", &errors);
    expect("concat(a,\n \"b\")", "ab", &errors);
    expect("concat(a + b,\nc,\"d\")", "abcd", &errors);
    expect("\"concat\"(a + b,\nc,\"d\")", "abcd", &errors);

    // logical and
    expect("a && b", "b", &errors);
    expect("a && \"\"", "", &errors);
    expect("\"\" && b", "", &errors);
    expect("\"\" && \"\"", "", &errors);
    expect("\"\" && abort()", "", &errors);   // test short-circuiting
    expect("t && abort()", NULL, &errors);

    // logical or
    expect("a || b", "a", &errors);
    expect("a || \"\"", "a", &errors);
    expect("\"\" || b", "b", &errors);
    expect("\"\" || \"\"", "", &errors);
    expect("a || abort()", "a", &errors);     // test short-circuiting
    expect("\"\" || abort()", NULL, &errors);

    // logical not
    expect("!a", "", &errors);
    expect("! \"\"", "t", &errors);
    expect("!!a", "t", &errors);

    // precedence
    expect("\"\" == \"\" && b", "b", &errors);
    expect("a + b == ab", "t", &errors);
    expect("ab == a + b", "t", &errors);
    expect("a + (b == ab)", "a", &errors);
    expect("(ab == a) + b", "b", &errors);

    // substring function
    expect("is_substring(cad, abracadabra)", "t", &errors);
    expect("is_substring(abrac, abracadabra)", "t", &errors);
    expect("is_substring(dabra, abracadabra)", "t", &errors);
    expect("is_substring(cad, abracxadabra)", "", &errors);
    expect("is_substring(abrac, axbracadabra)", "", &errors);
    expect("is_substring(dabra, abracadabrxa)", "", &errors);

    // ifelse function
    expect("ifelse(t, yes, no)", "yes", &errors);
    expect("ifelse(!t, yes, no)", "no", &errors);
    expect("ifelse(t, yes, abort())", "yes", &errors);
    expect("ifelse(!t, abort(), no)", "no", &errors);

    // if "statements"
    expect("if t then yes else no endif", "yes", &errors);
    expect("if \"\" then yes else no endif", "no", &errors);
    expect("if \"\" then yes endif", "", &errors);
    expect("if \"\"; t then yes endif", "yes", &errors);

    // numeric comparisons
    expect("less_than_int(3, 14)", "t", &errors);
    expect("less_than_int(14, 3)", "", &errors);
    expect("less_than_int(x, 3)", "", &errors);
    expect("less_than_int(3, x)", "", &errors);
    expect("greater_than_int(3, 14)", "", &errors);
    expect("greater_than_int(14, 3)", "t", &errors);
    expect("greater_than_int(x, 3)", "", &errors);
    expect("greater_than_int(3, x)", "", &errors);

    // big string
    expect(std::string(8192, 's').c_str(), std::string(8192, 's').c_str(), &errors);

    printf("\n");

    return errors;
}

void ExprDump(int depth, Expr* n, char* script) {
    printf("%*s", depth*2, "");
    char temp = script[n->end];
    script[n->end] = '\0';
    printf("%s %p (%d-%d) \"%s\"\n",
           n->name == NULL ? "(NULL)" : n->name, n->fn, n->start, n->end,
           script+n->start);
    script[n->end] = temp;
    int i;
    for (i = 0; i < n->argc; ++i) {
        ExprDump(depth+1, n->argv[i], script);
    }
}

int main(int argc, char** argv) {
    RegisterBuiltins();
    FinishRegistration();

    if (argc == 1) {
        return test() != 0;
    }

    FILE* f = fopen(argv[1], "r");
    if (f == NULL) {
        printf("%s: %s: No such file or directory\n", argv[0], argv[1]);
        return 1;
    }
    char buffer[8192];
    int size = fread(buffer, 1, 8191, f);
    fclose(f);
    buffer[size] = '\0';

    Expr* root;
    int error_count = 0;
    int error = parse_string(buffer, &root, &error_count);
    printf("parse returned %d; %d errors encountered\n", error, error_count);
    if (error == 0 || error_count > 0) {

        ExprDump(0, root, buffer);

        State state;
        state.cookie = NULL;
        state.script = buffer;
        state.errmsg = NULL;

        char* result = Evaluate(&state, root);
        if (result == NULL) {
            printf("result was NULL, message is: %s\n",
                   (state.errmsg == NULL ? "(NULL)" : state.errmsg));
            free(state.errmsg);
        } else {
            printf("result is [%s]\n", result);
        }
    }
    return 0;
}
