/**
 * Contains druntime startup and shutdown routines.
 *
 * Copyright: Copyright Digital Mars 2000 - 2018.
 * License: Distributed under the
 *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
 *    (See accompanying file LICENSE)
 * Authors:   Walter Bright, Sean Kelly
 * Source: $(DRUNTIMESRC rt/_dmain2.d)
 */

module rt.dmain2;

import core.atomic;
import core.internal.parseoptions : rt_parseOption;
import core.stdc.errno : errno;
import core.stdc.stdio : fflush, fprintf, fwrite, stderr, stdout;
import core.stdc.stdlib : alloca, EXIT_FAILURE, EXIT_SUCCESS, free, malloc, realloc;
import core.stdc.string : strerror;
import rt.config : rt_cmdline_enabled, rt_configOption;
import rt.memory;
import rt.sections;

version (Windows)
{
    import core.stdc.stdio : fileno;
    import core.stdc.wchar_ : wcslen;
    import core.sys.windows.basetsd : HANDLE;
    import core.sys.windows.shellapi : CommandLineToArgvW;
    import core.sys.windows.winbase : FreeLibrary, GetCommandLineW, GetProcAddress, IsDebuggerPresent, LoadLibraryW,
        LocalFree, WriteFile;
    import core.sys.windows.wincon : CONSOLE_SCREEN_BUFFER_INFO, GetConsoleOutputCP,
        GetConsoleScreenBufferInfo;
    import core.sys.windows.winnls : CP_UTF8, MultiByteToWideChar, WideCharToMultiByte;
    import core.sys.windows.winnt : WCHAR;
    import core.sys.windows.winuser : MB_ICONERROR, MessageBoxW;

    pragma(lib, "shell32.lib"); // needed for CommandLineToArgvW

    import core.stdc.stdio : _get_osfhandle;
}
else version (Posix)
{
    import core.stdc.string : strlen;
}

version (DigitalMars) version (AArch64)
    version = UseMalloc;   // cuz alloca() is not implemented yet

// not sure why we can't define this in one place, but this is to keep this
// module from importing core.runtime.
struct UnitTestResult
{
    size_t executed;
    size_t passed;
    bool runMain;
    bool summarize;
}

extern (C) void _d_monitor_staticctor() @nogc nothrow;
extern (C) void _d_monitor_staticdtor() @nogc nothrow;
extern (C) void _d_critical_init() @nogc nothrow;
extern (C) void _d_critical_term() @nogc nothrow;
extern (C) void gc_init();
extern (C) void gc_term();
extern (C) void thread_init() @nogc nothrow;
extern (C) void thread_term() @nogc nothrow;
extern (C) void rt_moduleCtor();
extern (C) void rt_moduleTlsCtor();
extern (C) void rt_moduleDtor();
extern (C) void rt_moduleTlsDtor();
extern (C) void thread_joinAll();
extern (C) UnitTestResult runModuleUnitTests();
extern (C) void _d_initMonoTime() @nogc nothrow;

version (CRuntime_Microsoft)
{
    extern(C) void init_msvc();
}

/* To get out-of-band access to the args[] passed to main().
 */

__gshared string[] _d_args = null;

extern (C) string[] rt_args()
{
    return _d_args;
}

// This variable is only ever set by a debugger on initialization so it should
// be fine to leave it as __gshared.
extern (C) __gshared bool rt_trapExceptions = true;

alias ExceptionHandler = void delegate(Throwable);

/**
 * Keep track of how often rt_init/rt_term were called.
 */
private shared size_t _initCount;

/**********************************************
 * Initialize druntime.
 * If a C program wishes to call D code, and there's no D main(), then it
 * must call rt_init() and rt_term().
 */
extern (C) int rt_init()
{
    /* @@BUG 11380 @@ Need to synchronize rt_init/rt_term calls for
       version (Shared) druntime, because multiple C threads might
       initialize different D libraries without knowing about the
       shared druntime. Also we need to attach any thread that calls
       rt_init. */
    if (atomicOp!"+="(_initCount, 1) > 1) return 1;

    version (CRuntime_Microsoft)
        init_msvc();

    _d_monitor_staticctor();
    _d_critical_init();

    try
    {
        initSections();
        // this initializes mono time before anything else to allow usage
        // in other druntime systems.
        _d_initMonoTime();
        thread_init();
        // TODO: fixme - calls GC.addRange -> Initializes GC
        initStaticDataGC();
        rt_moduleCtor();
        rt_moduleTlsCtor();
        return 1;
    }
    catch (Throwable t)
    {
        atomicStore!(MemoryOrder.raw)(_initCount, 0);
        _d_print_throwable(t);
    }
    _d_critical_term();
    _d_monitor_staticdtor();
    return 0;
}

/**********************************************
 * Terminate use of druntime.
 */
extern (C) int rt_term()
{
    if (atomicLoad!(MemoryOrder.raw)(_initCount) == 0) return 0; // was never initialized
    if (atomicOp!"-="(_initCount, 1)) return 1;

    try
    {
        rt_moduleTlsDtor();
        thread_joinAll();
        rt_moduleDtor();
        gc_term();
        thread_term();
        return 1;
    }
    catch (Throwable t)
    {
        _d_print_throwable(t);
    }
    finally
    {
        finiSections();
        _d_critical_term();
        _d_monitor_staticdtor();
    }
    return 0;
}

/**
 * Indicates whether druntime has been or is being initialized.
 */
bool isRuntimeInitialized() @nogc nothrow {
    return atomicLoad!(MemoryOrder.raw)(_initCount) != 0;
}

/**********************************************
 * Trace handler
 */
alias TraceHandler = Throwable.TraceInfo function(void* ptr);
private __gshared TraceHandler traceHandler = null;
private __gshared Throwable.TraceDeallocator traceDeallocator = null;


/**
 * Overrides the default trace hander with a user-supplied version.
 *
 * Params:
 *  h = The new trace handler.  Set to null to use the default handler.
 *  d = The new dealloactor to use.
 */
extern (C) void  rt_setTraceHandler(TraceHandler h, Throwable.TraceDeallocator d = null)
{
    traceHandler = h;
    traceDeallocator = d;
}

/**
 * Return the current trace handler
 */
extern (C) TraceHandler rt_getTraceHandler()
{
    return traceHandler;
}

extern (C) Throwable.TraceDeallocator rt_getTraceDeallocator()
{
    return traceDeallocator;
}

/**
 * This function will be called when an exception is constructed.  The
 * user-supplied trace handler will be called if one has been supplied,
 * otherwise no trace will be generated.
 *
 * Params:
 *  ptr = A pointer to the location from which to generate the trace, or null
 *        if the trace should be generated from within the trace handler
 *        itself.
 *
 * Returns:
 *  An object describing the current calling context or null if no handler is
 *  supplied.
 */
extern (C) Throwable.TraceInfo _d_traceContext(void* ptr = null)
{
    if (traceHandler is null)
        return null;
    return traceHandler(ptr);
}

/***********************************
 * Provide out-of-band access to the original C argc/argv
 * passed to this program via main(argc,argv).
 */

struct CArgs
{
    int argc;
    char** argv;
}

__gshared CArgs _cArgs;

extern (C) CArgs rt_cArgs() @nogc
{
    return _cArgs;
}

/// Type of the D main() function (`_Dmain`).
private alias MainFunc = extern(C) int function(char[][] args);

/**
 * Sets up the D char[][] command-line args, initializes druntime,
 * runs embedded unittests and then runs the given D main() function,
 * optionally catching and printing any unhandled exceptions.
 */
extern (C) int _d_run_main(int argc, char** argv, MainFunc mainFunc)
{
    // Set up _cArgs and array of D char[] slices, then forward to _d_run_main2

    // Remember the original C argc/argv
    _cArgs.argc = argc;
    _cArgs.argv = argv;

    version (Windows)
    {
        /* Because we want args[] to be UTF-8, and Windows doesn't guarantee that,
         * we ignore argc/argv and go get the Windows command line again as UTF-16.
         * Then, reparse into wargc/wargs, and then use Windows API to convert
         * to UTF-8.
         */
        const wCommandLine = GetCommandLineW();
        immutable size_t wCommandLineLength = wcslen(wCommandLine);
        int wargc;
        auto wargs = CommandLineToArgvW(wCommandLine, &wargc);
        // assert(wargc == argc); /* argc can be broken by Unicode arguments */

        // Allocate args[] on the stack - use wargc
        version (UseMalloc)
        {
            char[][] args = (cast(char[]*) malloc(wargc * (char[]).sizeof))[0 .. wargc];
            if (wargc)
                assert(args.ptr);
            scope (exit) free(args.ptr);
        }
        else
            char[][] args = (cast(char[]*) alloca(wargc * (char[]).sizeof))[0 .. wargc];

        // This is required because WideCharToMultiByte requires int as input.
        assert(wCommandLineLength <= cast(size_t) int.max, "Wide char command line length must not exceed int.max");

        immutable size_t totalArgsLength = WideCharToMultiByte(CP_UTF8, 0, wCommandLine, cast(int)wCommandLineLength, null, 0, null, null);
        {
            version (UseMalloc)
            {
                char* totalArgsBuff = cast(char*) malloc(totalArgsLength);
                if (totalArgsLength)
                    assert(totalArgsBuff);
                scope (exit) free(totalArgsBuff);
            }
            else
                char* totalArgsBuff = cast(char*) alloca(totalArgsLength);
            size_t j = 0;
            foreach (i; 0 .. wargc)
            {
                immutable size_t wlen = wcslen(wargs[i]);
                assert(wlen <= cast(size_t) int.max, "wlen cannot exceed int.max");
                immutable int len = WideCharToMultiByte(CP_UTF8, 0, &wargs[i][0], cast(int) wlen, null, 0, null, null);
                args[i] = totalArgsBuff[j .. j + len];
                if (len == 0)
                    continue;
                j += len;
                assert(j <= totalArgsLength);
                WideCharToMultiByte(CP_UTF8, 0, &wargs[i][0], cast(int) wlen, &args[i][0], len, null, null);
            }
        }
        LocalFree(wargs);
        wargs = null;
        wargc = 0;
    }
    else version (Posix)
    {
        // Allocate args[] on the stack
        version (UseMalloc)
        {
            char[][] args = (cast(char[]*) malloc(argc * (char[]).sizeof))[0 .. argc];
            if (argc)
                assert(args.ptr);
            scope (exit) free(args.ptr);
        }
        else
            char[][] args = (cast(char[]*) alloca(argc * (char[]).sizeof))[0 .. argc];

        size_t totalArgsLength = 0;
        foreach (i, ref arg; args)
        {
            arg = argv[i][0 .. strlen(argv[i])];
            totalArgsLength += arg.length;
        }
    }
    else
        static assert(0);

    return _d_run_main2(args, totalArgsLength, mainFunc);
}

/**
 * Windows-specific version for wide command-line arguments, e.g.,
 * from a wmain/wWinMain C entry point.
 * This wide version uses the specified arguments, unlike narrow
 * _d_run_main which uses the actual (wide) process arguments instead.
 */
version (Windows)
extern (C) int _d_wrun_main(int argc, wchar** wargv, MainFunc mainFunc)
{
     // Allocate args[] on the stack
    char[][] args = (cast(char[]*) alloca(argc * (char[]).sizeof))[0 .. argc];

    // 1st pass: compute each argument's length as UTF-16 and UTF-8
    size_t totalArgsLength = 0;
    foreach (i; 0 .. argc)
    {
        const warg = wargv[i];
        const size_t wlen = wcslen(warg) + 1; // incl. terminating null
        assert(wlen <= cast(size_t) int.max, "wlen cannot exceed int.max");
        const int len = WideCharToMultiByte(CP_UTF8, 0, warg, cast(int) wlen, null, 0, null, null);
        args[i] = (cast(char*) wlen)[0 .. len]; // args[i].ptr = wlen, args[i].length = len
        totalArgsLength += len;
    }

    // Allocate a single buffer for all (null-terminated) argument strings in UTF-8 on the stack
    char* utf8Buffer = cast(char*) alloca(totalArgsLength);

    // 2nd pass: convert to UTF-8 and finalize `args`
    char* utf8 = utf8Buffer;
    foreach (i; 0 .. argc)
    {
        const wlen = cast(int) args[i].ptr;
        const len = cast(int) args[i].length;
        WideCharToMultiByte(CP_UTF8, 0, wargv[i], wlen, utf8, len, null, null);
        args[i] = utf8[0 .. len-1]; // excl. terminating null
        utf8 += len;
    }

    // Set C argc/argv; argv is a new stack-allocated array of UTF-8 C strings
    char*[] argv = (cast(char**) alloca(argc * (char*).sizeof))[0 .. argc];
    foreach (i, ref arg; argv)
        arg = args[i].ptr;
    _cArgs.argc = argc;
    _cArgs.argv = argv.ptr;

    totalArgsLength -= argc; // excl. null terminator per arg
    return _d_run_main2(args, totalArgsLength, mainFunc);
}

private extern (C) int _d_run_main2(char[][] args, size_t totalArgsLength, MainFunc mainFunc)
{
    int result;

    version (FreeBSD) version (D_InlineAsm_X86)
    {
        /*
         * FreeBSD/i386 sets the FPU precision mode to 53 bit double.
         * Make it 64 bit extended.
         */
        ushort fpucw;
        asm
        {
            fstsw   fpucw;
            or      fpucw, 0b11_00_111111; // 11: use 64 bit extended-precision
                                           // 111111: mask all FP exceptions
            fldcw   fpucw;
        }
    }
    version (CRuntime_Microsoft)
    {
        // enable full precision for reals
        version (D_InlineAsm_X86_64)
        {
            asm
            {
                push    RAX;
                fstcw   word ptr [RSP];
                or      [RSP], 0b11_00_111111; // 11: use 64 bit extended-precision
                                               // 111111: mask all FP exceptions
                fldcw   word ptr [RSP];
                pop     RAX;
            }
        }
        else version (D_InlineAsm_X86)
        {
            asm
            {
                push    EAX;
                fstcw   word ptr [ESP];
                or      [ESP], 0b11_00_111111; // 11: use 64 bit extended-precision
                // 111111: mask all FP exceptions
                fldcw   word ptr [ESP];
                pop     EAX;
            }
        }
        else version (GNU_InlineAsm)
        {
            size_t fpu_cw;
            asm { "fstcw %0" : "=m" (fpu_cw); }
            fpu_cw |= 0b11_00_111111;  // 11: use 64 bit extended-precision
                                       // 111111: mask all FP exceptions
            asm { "fldcw %0" : "=m" (fpu_cw); }
        }
    }

    /* Create a copy of args[] on the stack to be used for main, so that rt_args()
     * cannot be modified by the user.
     * Note that when this function returns, _d_args will refer to garbage.
     */
    {
        _d_args = cast(string[]) args;

        auto length = args.length * (char[]).sizeof + totalArgsLength;
        version (UseMalloc)
        {
            auto buff = cast(char[]*) malloc(length);
            if (length)
                assert(buff);
            //scope (exit) buff;
        }
        else
            auto buff = cast(char[]*) alloca(length);

        char[][] argsCopy = buff[0 .. args.length];
        auto argBuff = cast(char*) (buff + args.length);
        size_t j = 0;
        bool parseOpts = rt_cmdline_enabled!();
        foreach (arg; args)
        {
            // Do not pass Druntime options to the program
            if (parseOpts && arg.length >= 6 && arg[0 .. 6] == "--DRT-")
                continue;
            // https://issues.dlang.org/show_bug.cgi?id=20459
            if (arg == "--")
                parseOpts = false;
            argsCopy[j++] = (argBuff[0 .. arg.length] = arg[]);
            argBuff += arg.length;
        }
        args = argsCopy[0..j];
    }

    auto useExceptionTrap = parseExceptionOptions();

    version (Windows)
    {
        if (IsDebuggerPresent())
            useExceptionTrap = false;
    }

    version (none)
    {
        // Causes test failures related to Fibers, not enabled by default yet
        import etc.linux.memoryerror;
        cast(void) registerMemoryAssertHandler();
    }

    void tryExec(scope void delegate() dg)
    {
        if (useExceptionTrap)
        {
            try
            {
                dg();
            }
            catch (Throwable t)
            {
                _d_print_throwable(t);
                result = EXIT_FAILURE;
            }
        }
        else
        {
            dg();
        }
    }

    // NOTE: The lifetime of a process is much like the lifetime of an object:
    //       it is initialized, then used, then destroyed.  If initialization
    //       fails, the successive two steps are never reached.  However, if
    //       initialization succeeds, then cleanup will occur even if the use
    //       step fails in some way.  Here, the use phase consists of running
    //       the user's main function.  If main terminates with an exception,
    //       the exception is handled and then cleanup begins.  An exception
    //       thrown during cleanup, however, will abort the cleanup process.
    void runAll()
    {
        if (rt_init())
        {
            version(Shared) version(CRuntime_Microsoft) version (DigitalMars)
            {
                auto exeHandle = handleForAddr(mainFunc);
                if (exeHandle)
                    if (!rt_initSharedModule(exeHandle))
                        exeHandle = null;
            }
            auto utResult = runModuleUnitTests();
            assert(utResult.passed <= utResult.executed);
            if (utResult.passed == utResult.executed)
            {
                if (utResult.summarize)
                {
                    if (utResult.passed == 0)
                        .fprintf(cast().stderr, "No unittests run\n");
                    else
                        .fprintf(cast().stderr, "%d modules passed unittests\n",
                                 cast(int)utResult.passed);
                }
                if (utResult.runMain)
                    tryExec({ result = mainFunc(args); });
                else
                    result = EXIT_SUCCESS;
            }
            else
            {
                if (utResult.summarize)
                    .fprintf(cast().stderr, "%d/%d modules FAILED unittests\n",
                             cast(int)(utResult.executed - utResult.passed),
                             cast(int)utResult.executed);
                result = EXIT_FAILURE;
            }
            version(Shared) version(CRuntime_Microsoft) version (DigitalMars)
            {
                if (exeHandle)
                    rt_termSharedModule(exeHandle);
            }
        }
        else
            result = EXIT_FAILURE;

        if (!rt_term())
            result = (result == EXIT_SUCCESS) ? EXIT_FAILURE : result;
    }

    tryExec(&runAll);

    // Issue 10344: flush stdout and return nonzero on failure
    if (.fflush(cast().stdout) != 0)
    {
        .fprintf(cast().stderr, "Failed to flush stdout: %s\n", .strerror(.errno));
        if (result == 0)
        {
            result = EXIT_FAILURE;
        }
    }

    return result;
}

private void formatThrowable(Throwable t, scope void delegate(in char[] s) nothrow sink)
{
    foreach (u; t)
    {
        u.toString(sink); sink("\n");

        auto e = cast(Error)u;
        if (e is null || e.bypassedException is null) continue;

        sink("=== Bypassed ===\n");
        foreach (t2; e.bypassedException)
        {
            t2.toString(sink); sink("\n");
        }
        sink("=== ~Bypassed ===\n");
    }
}

private auto parseExceptionOptions()
{
    const optName = "trapExceptions";
    auto option = rt_configOption(optName);
    auto trap = rt_trapExceptions;
    if (option.length)
        rt_parseOption(optName, option, trap, "");
    return trap;
}

extern (C) void _d_print_throwable(Throwable t)
{
    // On Windows, a console may not be present to print the output to.
    // Show a message box instead. If the console is present, convert to
    // the correct encoding.
    version (Windows)
    {
        static struct WSink
        {
            WCHAR* ptr; size_t len;

            void sink(in char[] s) scope nothrow
            {
                if (!s.length) return;
                const swlen = MultiByteToWideChar(
                        CP_UTF8, 0, s.ptr, cast(int)s.length, null, 0);
                if (!swlen) return;

                auto newPtr = cast(WCHAR*)realloc(ptr,
                        (this.len + swlen + 1) * WCHAR.sizeof);
                if (!newPtr) return;
                ptr = newPtr;
                const written = MultiByteToWideChar(
                        CP_UTF8, 0, s.ptr, cast(int)s.length, ptr+len, swlen);
                len += written;
            }

            typeof(ptr) get() { if (ptr) ptr[len] = 0; return ptr; }

            void free() { .free(ptr); }
        }

        HANDLE windowsHandle(int fd)
        {
            return cast(HANDLE)_get_osfhandle(fd);
        }

        // ensure the exception is shown at the beginning of the line, while also
        // checking whether stderr is a valid file
        int written = fprintf(cast()stderr, "\n");
        if (written <= 0)
        {
            WSink buf;
            formatThrowable(t, &buf.sink);

            if (buf.ptr)
            {
                WSink caption;
                if (t)
                    caption.sink(typeid(t).name);

                // Avoid static user32.dll dependency for console applications
                // by loading it dynamically as needed
                if (auto user32 = LoadLibraryW("user32.dll"))
                {
                    alias PMessageBoxW = typeof(&MessageBoxW) ;
                    if (auto pMessageBoxW = cast(PMessageBoxW) GetProcAddress(user32, "MessageBoxW"))
                        pMessageBoxW(null, buf.get(), caption.get(), MB_ICONERROR);
                    FreeLibrary(user32);
                }
                caption.free();
                buf.free();
            }
            return;
        }
        auto hStdErr = windowsHandle(fileno(cast()stderr));
        CONSOLE_SCREEN_BUFFER_INFO sbi = void;
        const isConsole = GetConsoleScreenBufferInfo(hStdErr, &sbi) != 0;
        if (isConsole)
        {
            WSink buf;
            formatThrowable(t, &buf.sink);

            if (buf.ptr)
            {
                uint codepage = GetConsoleOutputCP();
                const slen = WideCharToMultiByte(codepage, 0,
                        buf.ptr, cast(int)buf.len, null, 0, null, null);
                if (auto sptr = cast(char*)malloc(slen * char.sizeof))
                {
                    WideCharToMultiByte(codepage, 0,
                        buf.ptr, cast(int)buf.len, sptr, slen, null, null);
                    WriteFile(hStdErr, sptr, slen, null, null);
                    free(sptr);
                }
                buf.free();
            }
            return;
        }
    }

    void sink(in char[] buf) scope nothrow
    {
        fwrite(buf.ptr, char.sizeof, buf.length, cast()stderr);
    }
    formatThrowable(t, &sink);
}
