/*
 * 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 "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);

    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;
}
