// 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 <stdlib.h>
#include <string.h>

#include <jsapi.h>

#include "help.h"
#include "util.h"
#include "utf8.h"


size_t
slurp_file(const char* file, char** outbuf_p)
{
    FILE* fp;
    char fbuf[16384];
    char *buf = NULL;
    char* tmp;
    size_t nread = 0;
    size_t buflen = 0;

    if(strcmp(file, "-") == 0) {
        fp = stdin;
    } else {
        fp = fopen(file, "r");
        if(fp == NULL) {
            fprintf(stderr, "Failed to read file: %s\n", file);
            exit(3);
        }
    }

    while((nread = fread(fbuf, 1, 16384, fp)) > 0) {
        if(buf == NULL) {
            buf = (char*) malloc(nread + 1);
            if(buf == NULL) {
                fprintf(stderr, "Out of memory.\n");
                exit(3);
            }
            memcpy(buf, fbuf, nread);
        } else {
            tmp = (char*) malloc(buflen + nread + 1);
            if(tmp == NULL) {
                fprintf(stderr, "Out of memory.\n");
                exit(3);
            }
            memcpy(tmp, buf, buflen);
            memcpy(tmp+buflen, fbuf, nread);
            free(buf);
            buf = tmp;
        }
        buflen += nread;
        buf[buflen] = '\0';
    }
    *outbuf_p = buf;
    return buflen + 1;
}

couch_args*
couch_parse_args(int argc, const char* argv[])
{
    couch_args* args;
    int i = 1;

    args = (couch_args*) malloc(sizeof(couch_args));
    if(args == NULL)
        return NULL;

    memset(args, '\0', sizeof(couch_args));
    args->stack_size = 64L * 1024L * 1024L;

    while(i < argc) {
        if(strcmp("-h", argv[i]) == 0) {
            DISPLAY_USAGE;
            exit(0);
        } else if(strcmp("-V", argv[i]) == 0) {
            DISPLAY_VERSION;
            exit(0);
        } else if(strcmp("-H", argv[i]) == 0) {
            args->use_http = 1;
        } else if(strcmp("-S", argv[i]) == 0) {
            args->stack_size = atoi(argv[++i]);
            if(args->stack_size <= 0) {
                fprintf(stderr, "Invalid stack size.\n");
                exit(2);
            }
        } else if(strcmp("-u", argv[i]) == 0) {
            args->uri_file = argv[++i];
        } else if(strcmp("--", argv[i]) == 0) {
            i++;
            break;
        } else {
            break;
        }
        i++;
    }

    if(i >= argc) {
        DISPLAY_USAGE;
        exit(3);
    }
    args->scripts = argv + i;

    return args;
}


int
couch_fgets(char* buf, int size, FILE* fp)
{
    int n, i, c;

    if(size <= 0) return -1;
    n = size - 1;

    for(i = 0; i < n && (c = getc(fp)) != EOF; i++) {
        buf[i] = c;
        if(c == '\n') {
            i++;
            break;
        }
    }

    buf[i] = '\0';
    return i;
}


JSString*
couch_readline(JSContext* cx, FILE* fp)
{
    JSString* str;
    char* bytes = NULL;
    char* tmp = NULL;
    size_t used = 0;
    size_t byteslen = 256;
    size_t readlen = 0;

    bytes = JS_malloc(cx, byteslen);
    if(bytes == NULL) return NULL;
    
    while((readlen = couch_fgets(bytes+used, byteslen-used, fp)) > 0) {
        used += readlen;
        
        if(bytes[used-1] == '\n') {
            bytes[used-1] = '\0';
            break;
        }
        
        // Double our buffer and read more.
        byteslen *= 2;
        tmp = JS_realloc(cx, bytes, byteslen);
        if(!tmp) {
            JS_free(cx, bytes);
            return NULL;
        }
        
        bytes = tmp;
    }

    // Treat empty strings specially
    if(used == 0) {
        JS_free(cx, bytes);
        return JSVAL_TO_STRING(JS_GetEmptyStringValue(cx));
    }

    // Shring the buffer to the actual data size
    tmp = JS_realloc(cx, bytes, used);
    if(!tmp) {
        JS_free(cx, bytes);
        return NULL;
    }
    bytes = tmp;
    byteslen = used;

    str = dec_string(cx, bytes, byteslen);
    JS_free(cx, bytes);
    return str;
}


JSString*
couch_readfile(JSContext* cx, const char* filename)
{
    JSString *string;
    size_t byteslen;
    char *bytes;

    if((byteslen = slurp_file(filename, &bytes))) {
        string = dec_string(cx, bytes, byteslen);

        free(bytes);
        return string;
    }
    return NULL;    
}


void
couch_print(JSContext* cx, uintN argc, jsval* argv)
{
    char *bytes = NULL;
    FILE *stream = stdout;

    if (argc) {
        if (argc > 1 && argv[1] == JSVAL_TRUE) {
          stream = stderr;
        }
        bytes = enc_string(cx, argv[0], NULL);
        if(!bytes) return;
        fprintf(stream, "%s", bytes);
        JS_free(cx, bytes);
    }

    fputc('\n', stream);
    fflush(stream);
}


void
couch_error(JSContext* cx, const char* mesg, JSErrorReport* report)
{
    jsval v, replace;
    char* bytes;
    JSObject* regexp, *stack;
    jsval re_args[2];

    if(!report || !JSREPORT_IS_WARNING(report->flags))
    {
        fprintf(stderr, "%s\n", mesg);

        // Print a stack trace, if available.
        if (JSREPORT_IS_EXCEPTION(report->flags) &&
            JS_GetPendingException(cx, &v))
        {
            // Clear the exception before an JS method calls or the result is
            // infinite, recursive error report generation.
            JS_ClearPendingException(cx);

            // Use JS regexp to indent the stack trace.
            // If the regexp can't be created, don't JS_ReportError since it is
            // probably not productive to wind up here again.
#ifdef SM185
            if(JS_GetProperty(cx, JSVAL_TO_OBJECT(v), "stack", &v) &&
               (regexp = JS_NewRegExpObjectNoStatics(
                   cx, "^(?=.)", 6, JSREG_GLOB | JSREG_MULTILINE)))
#else
            if(JS_GetProperty(cx, JSVAL_TO_OBJECT(v), "stack", &v) &&
               (regexp = JS_NewRegExpObject(
                   cx, "^(?=.)", 6, JSREG_GLOB | JSREG_MULTILINE)))
#endif
            {
                // Set up the arguments to ``String.replace()``
                re_args[0] = OBJECT_TO_JSVAL(regexp);
                re_args[1] = STRING_TO_JSVAL(JS_InternString(cx, "\t"));

                // Perform the replacement
                if(JS_ValueToObject(cx, v, &stack) &&
                   JS_GetProperty(cx, stack, "replace", &replace) &&
                   JS_CallFunctionValue(cx, stack, replace, 2, re_args, &v))
                {
                    // Print the result
                    bytes = enc_string(cx, v, NULL);
                    fprintf(stderr, "Stacktrace:\n%s", bytes);
                    JS_free(cx, bytes);
                }
            }
        }
    }
}


JSBool
couch_load_funcs(JSContext* cx, JSObject* obj, JSFunctionSpec* funcs)
{
    JSFunctionSpec* f;
    for(f = funcs; f->name != NULL; f++) {
        if(!JS_DefineFunction(cx, obj, f->name, f->call, f->nargs, f->flags)) {
            fprintf(stderr, "Failed to create function: %s\n", f->name);
            return JS_FALSE;
        }
    }
    return JS_TRUE;
}
