/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 * vim: set ts=8 sts=4 et sw=4 tw=99:
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// OSObject.h - os object for exposing posix system calls in the JS shell

#include "shell/OSObject.h"

#include <errno.h>
#include <stdlib.h>
#ifdef XP_WIN
#include <direct.h>
#include <process.h>
#include <string.h>
#else
#include <sys/wait.h>
#include <unistd.h>
#endif

#include "jsapi.h"
// For JSFunctionSpecWithHelp
#include "jsfriendapi.h"
#include "jsobj.h"
#ifdef XP_WIN
# include "jswin.h"
#endif
#include "jswrapper.h"

#include "js/Conversions.h"
#include "shell/jsshell.h"
#include "vm/TypedArrayObject.h"

#include "jsobjinlines.h"

#ifdef XP_WIN
# define PATH_MAX (MAX_PATH > _MAX_DIR ? MAX_PATH : _MAX_DIR)
# define getcwd _getcwd
#else
# include <libgen.h>
#endif

using js::shell::RCFile;

static RCFile** gErrFilePtr = nullptr;
static RCFile** gOutFilePtr = nullptr;

using namespace JS;

namespace js {
namespace shell {

/*
 * Resolve a (possibly) relative filename to an absolute path. If
 * |scriptRelative| is true, then the result will be relative to the directory
 * containing the currently-running script, or the current working directory if
 * the currently-running script is "-e" (namely, you're using it from the
 * command line.) Otherwise, it will be relative to the current working
 * directory.
 */
JSString*
ResolvePath(JSContext* cx, HandleString filenameStr, PathResolutionMode resolveMode)
{
    JSAutoByteString filename(cx, filenameStr);
    if (!filename)
        return nullptr;

    const char* pathname = filename.ptr();
    if (pathname[0] == '/')
        return filenameStr;
#ifdef XP_WIN
    // Various forms of absolute paths per http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx
    // "\..."
    if (pathname[0] == '\\')
        return filenameStr;
    // "C:\..."
    if (strlen(pathname) > 3 && isalpha(pathname[0]) && pathname[1] == ':' && pathname[2] == '\\')
        return filenameStr;
    // "\\..."
    if (strlen(pathname) > 2 && pathname[1] == '\\' && pathname[2] == '\\')
        return filenameStr;
#endif

    /* Get the currently executing script's name. */
    JS::AutoFilename scriptFilename;
    if (!DescribeScriptedCaller(cx, &scriptFilename))
        return nullptr;

    if (!scriptFilename.get())
        return nullptr;

    if (strcmp(scriptFilename.get(), "-e") == 0 || strcmp(scriptFilename.get(), "typein") == 0)
        resolveMode = RootRelative;

    static char buffer[PATH_MAX+1];
    if (resolveMode == ScriptRelative) {
#ifdef XP_WIN
        // The docs say it can return EINVAL, but the compiler says it's void
        _splitpath(scriptFilename.get(), nullptr, buffer, nullptr, nullptr);
#else
        strncpy(buffer, scriptFilename.get(), PATH_MAX+1);
        if (buffer[PATH_MAX] != '\0')
            return nullptr;

        // dirname(buffer) might return buffer, or it might return a
        // statically-allocated string
        memmove(buffer, dirname(buffer), strlen(buffer) + 1);
#endif
    } else {
        const char* cwd = getcwd(buffer, PATH_MAX);
        if (!cwd)
            return nullptr;
    }

    size_t len = strlen(buffer);
    buffer[len] = '/';
    strncpy(buffer + len + 1, pathname, sizeof(buffer) - (len+1));
    if (buffer[PATH_MAX] != '\0')
        return nullptr;

    return JS_NewStringCopyZ(cx, buffer);
}

static JSObject*
FileAsTypedArray(JSContext* cx, const char* pathname)
{
    FILE* file = fopen(pathname, "rb");
    if (!file) {
        JS_ReportError(cx, "can't open %s: %s", pathname, strerror(errno));
        return nullptr;
    }
    AutoCloseInputFile autoClose(file);

    RootedObject obj(cx);
    if (fseek(file, 0, SEEK_END) != 0) {
        JS_ReportError(cx, "can't seek end of %s", pathname);
    } else {
        size_t len = ftell(file);
        if (fseek(file, 0, SEEK_SET) != 0) {
            JS_ReportError(cx, "can't seek start of %s", pathname);
        } else {
            obj = JS_NewUint8Array(cx, len);
            if (!obj)
                return nullptr;
            char* buf = (char*) obj->as<js::TypedArrayObject>().viewData();
            size_t cc = fread(buf, 1, len, file);
            if (cc != len) {
                JS_ReportError(cx, "can't read %s: %s", pathname,
                               (ptrdiff_t(cc) < 0) ? strerror(errno) : "short read");
                obj = nullptr;
            }
        }
    }
    return obj;
}

static bool
ReadFile(JSContext* cx, unsigned argc, jsval* vp, bool scriptRelative)
{
    CallArgs args = CallArgsFromVp(argc, vp);

    if (args.length() < 1 || args.length() > 2) {
        JS_ReportErrorNumber(cx, js::shell::my_GetErrorMessage, nullptr,
                             args.length() < 1 ? JSSMSG_NOT_ENOUGH_ARGS : JSSMSG_TOO_MANY_ARGS,
                             "snarf");
        return false;
    }

    if (!args[0].isString() || (args.length() == 2 && !args[1].isString())) {
        JS_ReportErrorNumber(cx, js::shell::my_GetErrorMessage, nullptr, JSSMSG_INVALID_ARGS, "snarf");
        return false;
    }

    RootedString givenPath(cx, args[0].toString());
    RootedString str(cx, js::shell::ResolvePath(cx, givenPath, scriptRelative ? ScriptRelative : RootRelative));
    if (!str)
        return false;

    JSAutoByteString filename(cx, str);
    if (!filename)
        return false;

    if (args.length() > 1) {
        JSString* opt = JS::ToString(cx, args[1]);
        if (!opt)
            return false;
        bool match;
        if (!JS_StringEqualsAscii(cx, opt, "binary", &match))
            return false;
        if (match) {
            JSObject* obj;
            if (!(obj = FileAsTypedArray(cx, filename.ptr())))
                return false;
            args.rval().setObject(*obj);
            return true;
        }
    }

    if (!(str = FileAsString(cx, filename.ptr())))
        return false;
    args.rval().setString(str);
    return true;
}

static bool
osfile_readFile(JSContext* cx, unsigned argc, jsval* vp)
{
    return ReadFile(cx, argc, vp, false);
}

static bool
osfile_readRelativeToScript(JSContext* cx, unsigned argc, jsval* vp)
{
    return ReadFile(cx, argc, vp, true);
}

static bool
Redirect(JSContext* cx, FILE* fp, HandleString relFilename)
{
    RootedString filename(cx, ResolvePath(cx, relFilename, RootRelative));
    if (!filename)
        return false;
    JSAutoByteString filenameABS(cx, filename);
    if (!filenameABS)
        return false;
    if (freopen(filenameABS.ptr(), "wb", fp) == nullptr) {
        JS_ReportError(cx, "cannot redirect to %s: %s", filenameABS.ptr(), strerror(errno));
        return false;
    }
    return true;
}

static bool
osfile_redirect(JSContext* cx, unsigned argc, jsval* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);

    if (args.length() < 1 || args.length() > 2) {
        JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, JSSMSG_INVALID_ARGS, "redirect");
        return false;
    }

    if (args[0].isString()) {
        RootedString stdoutPath(cx, args[0].toString());
        if (!stdoutPath)
            return false;
        if (!Redirect(cx, stdout, stdoutPath))
            return false;
    }

    if (args.length() > 1 && args[1].isString()) {
        RootedString stderrPath(cx, args[1].toString());
        if (!stderrPath)
            return false;
        if (!Redirect(cx, stderr, stderrPath))
            return false;
    }

    args.rval().setUndefined();
    return true;
}
<<<<<<<

|||||||
=======

/* static */ RCFile*
RCFile::create(JSContext* cx, const char* filename, const char* mode)
{
    FILE* fp = fopen(filename, mode);
    if (!fp)
        return nullptr;

    RCFile* file = cx->new_<RCFile>(fp);
    if (!file) {
        fclose(fp);
        return nullptr;
    }

    return file;
}

void
RCFile::close()
{
    if (fp)
        fclose(fp);
    fp = nullptr;
}

bool
RCFile::release()
{
    if (--numRefs)
        return false;
    this->close();
    return true;
}

class FileObject : public JSObject {
    enum : uint32_t {
        FILE_SLOT = 0,
        NUM_SLOTS
    };

  public:
    static const js::Class class_;

    static FileObject* create(JSContext* cx, RCFile* file) {
        JSObject* obj = js::NewObjectWithClassProto(cx, &class_, JS::NullPtr());
        if (!obj)
            return nullptr;

        FileObject* fileObj = &obj->as<FileObject>();
        fileObj->setRCFile(file);
        file->acquire();
        return fileObj;
    }

    static void finalize(FreeOp* fop, JSObject* obj) {
        FileObject* fileObj = &obj->as<FileObject>();
        RCFile* file = fileObj->rcFile();
        if (file->release()) {
            fileObj->setRCFile(nullptr);
            fop->delete_(file);
        }
    }

    bool isOpen() {
        RCFile* file = rcFile();
        return file && file->isOpen();
    }

    void close() {
        if (!isOpen())
            return;
        rcFile()->close();
    }

    RCFile* rcFile() {
        return reinterpret_cast<RCFile*>(js::GetReservedSlot(this, FILE_SLOT).toPrivate());
    }

  private:

    void setRCFile(RCFile* file) {
        js::SetReservedSlot(this, FILE_SLOT, PrivateValue(file));
    }
};

const js::Class FileObject::class_ = {
    "File",
    JSCLASS_HAS_RESERVED_SLOTS(FileObject::NUM_SLOTS),
    nullptr,               /* addProperty */
    nullptr,               /* delProperty */
    nullptr,               /* getProperty */
    nullptr,               /* setProperty */
    nullptr,               /* enumerate */
    nullptr,               /* resolve */
    nullptr,               /* mayResolve */
    nullptr,               /* convert */
    FileObject::finalize,  /* finalize */
    nullptr,               /* call */
    nullptr,               /* hasInstance */
    nullptr,               /* construct */
    nullptr                /* trace */
};

static FileObject*
redirect(JSContext* cx, HandleString relFilename, RCFile** globalFile)
{
    RootedString filename(cx, ResolvePath(cx, relFilename, RootRelative));
    if (!filename)
        return nullptr;
    JSAutoByteString filenameABS(cx, filename);
    if (!filenameABS)
        return nullptr;
    RCFile* file = RCFile::create(cx, filenameABS.ptr(), "wb");
    if (!file) {
        JS_ReportError(cx, "cannot redirect to %s: %s", filenameABS.ptr(), strerror(errno));
        return nullptr;
    }

    // The global gOutFile acquires ownership of the new file, releases
    // ownership of its old file, and we return a FileObject owning the old
    // file.
    file->acquire(); // Global owner of new file

    FileObject* fileObj = FileObject::create(cx, *globalFile); // Newly created owner of old file
    if (!fileObj) {
        file->release();
        return nullptr;
    }

    (*globalFile)->release(); // Release (global) ownership of old file.
    *globalFile = file;

    return fileObj;
}

static bool
Redirect(JSContext* cx, const CallArgs& args, RCFile** outFile)
{
    if (args.length() > 1) {
        JS_ReportErrorNumber(cx, js::shell::my_GetErrorMessage, nullptr, JSSMSG_INVALID_ARGS, "redirect");
        return false;
    }

    RCFile* oldFile = *outFile;
    RootedObject oldFileObj(cx, FileObject::create(cx, oldFile));
    if (!oldFileObj)
        return false;

    if (args.get(0).isUndefined()) {
        args.rval().setObject(*oldFileObj);
        return true;
    }

    if (args[0].isObject()) {
        RootedObject fileObj(cx, js::CheckedUnwrap(&args[0].toObject()));
        if (!fileObj)
            return false;
        if (fileObj->is<FileObject>()) {
            // Passed in a FileObject. Create a FileObject for the previous
            // global file, and set the global file to the passed-in one.
            *outFile = fileObj->as<FileObject>().rcFile();
            (*outFile)->acquire();
            oldFile->release();

            args.rval().setObject(*oldFileObj);
            return true;
        }
    }

    RootedString filename(cx, JS::ToString(cx, args[0]));
    if (!filename)
        return false;

    if (!redirect(cx, filename, outFile))
        return false;

    args.rv