/* Python interpreter main program */

#include "Python.h"
#include "pycore_call.h"          // _PyObject_CallNoArgs()
#include "pycore_fileutils.h"     // struct _Py_stat_struct
#include "pycore_import.h"        // _PyImport_Fini2()
#include "pycore_initconfig.h"    // _PyArgv
#include "pycore_interp.h"        // _PyInterpreterState.sysdict
#include "pycore_long.h"          // _PyLong_GetOne()
#include "pycore_pathconfig.h"    // _PyPathConfig_ComputeSysPath0()
#include "pycore_pylifecycle.h"   // _Py_PreInitializeFromPyArgv()
#include "pycore_pystate.h"       // _PyInterpreterState_GET()
#include "pycore_pythonrun.h"     // _PyRun_AnyFile()
#include "pycore_sysmodule.h"     // _PySys_FormatV()
#include "pycore_tuple.h"         // _PyTuple_FromPair
#include "pycore_unicodeobject.h" // _PyUnicode_Dedent()

/* Includes for exit_sigint() */
#include <stdio.h>                // perror()
#ifdef HAVE_SIGNAL_H
#  include <signal.h>             // SIGINT
#endif
#if defined(HAVE_GETPID) && defined(HAVE_UNISTD_H)
#  include <unistd.h>             // getpid()
#endif
#ifdef MS_WINDOWS
#  include <windows.h>            // STATUS_CONTROL_C_EXIT
#endif
/* End of includes for exit_sigint() */

#define COPYRIGHT \
    "Type \"help\", \"copyright\", \"credits\" or \"license\" " \
    "for more information."

/* --- pymain_init() ---------------------------------------------- */

static PyStatus
pymain_init(const _PyArgv *args)
{
    PyStatus status;

    status = _PyRuntime_Initialize();
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    PyPreConfig preconfig;
    PyPreConfig_InitPythonConfig(&preconfig);

    status = _Py_PreInitializeFromPyArgv(&preconfig, args);
    if (_PyStatus_EXCEPTION(status)) {
        return status;
    }

    PyConfig config;
    PyConfig_InitPythonConfig(&config);

    /* pass NULL as the config: config is read from command line arguments,
       environment variables, configuration files */
    if (args->use_bytes_argv) {
        status = PyConfig_SetBytesArgv(&config, args->argc, args->bytes_argv);
    }
    else {
        status = PyConfig_SetArgv(&config, args->argc, args->wchar_argv);
    }
    if (_PyStatus_EXCEPTION(status)) {
        goto done;
    }

    status = Py_InitializeFromConfig(&config);
    if (_PyStatus_EXCEPTION(status)) {
        goto done;
    }
    status = _PyStatus_OK();

done:
    PyConfig_Clear(&config);
    return status;
}


/* --- pymain_run_python() ---------------------------------------- */

static void
pymain_error_format(const char *format, ...)
{
    va_list vargs;
    va_start(vargs, format);

    PySys_WriteStderr("python: ");
    _PySys_FormatV(&_Py_ID(stderr), stderr, format, vargs);
    PySys_WriteStderr("\n");

    va_end(vargs);
}

// See also pyrun_error()
static void
pymain_error(const char *msg)
{
    PySys_FormatStderr("python: %s\n", msg);
}

static int
pymain_check_signals(void)
{
    return Py_MakePendingCalls();
}

/* Non-zero if filename, command (-c) or module (-m) is set
   on the command line */
static inline int config_run_code(const PyConfig *config)
{
    return (config->run_command != NULL
            || config->run_filename != NULL
            || config->run_module != NULL);
}


/* Return non-zero if stdin is a TTY or if -i command line option is used */
static int
stdin_is_interactive(const PyConfig *config)
{
    return (isatty(fileno(stdin)) || config->interactive);
}


/* Display the current Python exception and return an exitcode */
static int
pymain_err_print(int *exitcode_p)
{
    int exitcode;
    if (_Py_HandleSystemExitAndKeyboardInterrupt(&exitcode)) {
        *exitcode_p = exitcode;
        return 1;
    }

    PyErr_Print();
    return 0;
}


static int
pymain_exit_err_print(void)
{
    int exitcode = 1;
    pymain_err_print(&exitcode);
    return exitcode;
}


// If filename is a package (ex: directory or ZIP file) which contains
// __main__.py, main_importer_path is set to filename and will be prepended to
// sys.path.
//
// Otherwise, main_importer_path is left unchanged.
//
// Write an exitcode into *exitcode and return 1 if we have to exit Python.
// Return 0 otherwise.
static int
pymain_get_importer(const PyConfig *config, PyObject **importer_p,
                    int *exitcode)
{
    const wchar_t *filename = config->run_filename;
    if (filename == NULL) {
        return 0;
    }

    PyObject *sys_path0 = PyUnicode_FromWideChar(filename, -1);
    if (sys_path0 == NULL) {
        goto error;
    }

    PyObject *importer = PyImport_GetImporter(sys_path0);
    if (importer == NULL) {
        goto error;
    }

    if (importer == Py_None) {
        Py_DECREF(sys_path0);
        Py_DECREF(importer);
        return 0;
    }

    Py_DECREF(importer);
    *importer_p = sys_path0;
    return 0;

error:
    Py_XDECREF(sys_path0);

    pymain_error("Failed checking if argv[0] is an import path entry:");
    return pymain_err_print(exitcode);
}


static int
pymain_sys_path_add_path0(PyObject *path0)
{
    PyObject *sys_path;
    PyInterpreterState *interp = _PyInterpreterState_GET();
    PyObject *sysdict = interp->sysdict;
    if (sysdict != NULL) {
        sys_path = PyDict_GetItemWithError(sysdict, &_Py_ID(path));
        if (sys_path == NULL && PyErr_Occurred()) {
            return -1;
        }
    }
    else {
        sys_path = NULL;
    }
    if (sys_path == NULL) {
        PyErr_SetString(PyExc_RuntimeError, "unable to get sys.path");
        return -1;
    }

    if (PyList_Insert(sys_path, 0, path0)) {
        return -1;
    }
    return 0;
}


static void
pymain_header(const PyConfig *config)
{
    if (config->quiet) {
        return;
    }

    if (!config->verbose && (config_run_code(config) || !stdin_is_interactive(config))) {
        return;
    }

    fprintf(stderr, "Python %s on %s\n", Py_GetVersion(), Py_GetPlatform());
    if (config->site_import) {
        fprintf(stderr, "%s\n", COPYRIGHT);
    }
}


static int
pymain_import_readline(const PyConfig *config)
{
    if (pymain_check_signals() < 0) {
        return -1;
    }

    if (config->isolated) {
        return 0;
    }
    if (!config->inspect && config_run_code(config)) {
        return 0;
    }
    if (!isatty(fileno(stdin))) {
        return 0;
    }

    PyObject *mod = PyImport_ImportModule("readline");
    if (mod == NULL) {
        PyErr_Clear();
    }
    else {
        Py_DECREF(mod);
    }

    mod = PyImport_ImportModule("rlcompleter");
    if (mod == NULL) {
        PyErr_Clear();
    }
    else {
        Py_DECREF(mod);
    }
    return 0;
}


static int
pymain_run_command(wchar_t *command)
{
    PyObject *unicode, *bytes;

    unicode = PyUnicode_FromWideChar(command, -1);
    if (unicode == NULL) {
        goto error;
    }

    if (PySys_Audit("cpython.run_command", "O", unicode) < 0) {
        return pymain_exit_err_print();
    }

    Py_SETREF(unicode, _PyUnicode_Dedent(unicode));
    if (unicode == NULL) {
        goto error;
    }

    bytes = PyUnicode_AsUTF8String(unicode);
    Py_DECREF(unicode);
    if (bytes == NULL) {
        goto error;
    }

    PyCompilerFlags cf = _PyCompilerFlags_INIT;
    cf.cf_flags |= PyCF_IGNORE_COOKIE;
    PyObject *result = NULL;
    PyObject *string_obj = PyUnicode_FromString("<string>");
    if (string_obj != NULL) {
        result = _PyRun_SimpleString(PyBytes_AsString(bytes),
                                     string_obj, &cf);
        Py_DECREF(string_obj);
    }
    Py_DECREF(bytes);
    if (result == NULL) {
        return pymain_exit_err_print();
    }
    return 0;

error:
    pymain_error("Unable to decode the command from the command line:");
    return pymain_exit_err_print();
}


static int
pymain_run_pyrepl(int pythonstartup)
{
    int exitcode = 0;
    PyObject *console = NULL;
    PyObject *empty_tuple = NULL;
    PyObject *kwargs = NULL;
    PyObject *console_result = NULL;
    PyObject *main_module = NULL;

    PyObject *pyrepl = PyImport_ImportModule("_pyrepl.main");
    if (pyrepl == NULL) {
        pymain_error("Could not import _pyrepl.main");
        goto error;
    }

    console = PyObject_GetAttrString(pyrepl, "interactive_console");
    if (console == NULL) {
        pymain_error("Could not access _pyrepl.main.interactive_console");
        goto error;
    }

    empty_tuple = PyTuple_New(0);
    if (empty_tuple == NULL) {
        goto error;
    }
    kwargs = PyDict_New();
    if (kwargs == NULL) {
        goto error;
    }

    main_module = PyImport_AddModuleRef("__main__");
    if (main_module == NULL) {
        goto error;
    }

    PyObject *value = pythonstartup ? Py_True : Py_False;
    if (PyDict_SetItemString(kwargs, "mainmodule", main_module)
        || PyDict_SetItemString(kwargs, "pythonstartup", value))
    {
        goto error;
    }

    console_result = PyObject_Call(console, empty_tuple, kwargs);
    if (console_result == NULL) {
        goto error;
    }

done:
    Py_XDECREF(console_result);
    Py_XDECREF(kwargs);
    Py_XDECREF(empty_tuple);
    Py_XDECREF(console);
    Py_XDECREF(pyrepl);
    Py_XDECREF(main_module);
    return exitcode;

error:
    exitcode = pymain_exit_err_print();
    goto done;
}


static int
pymain_run_module(const wchar_t *modname, int set_argv0)
{
    int exitcode = 0;
    PyObject *module = NULL;
    PyObject *runmodule = NULL;
    PyObject *runargs = NULL;
    PyObject *result = NULL;

    if (PySys_Audit("cpython.run_module", "u", modname) < 0) {
        goto error;
    }

    runmodule = PyImport_ImportModuleAttrString("runpy",
                                                "_run_module_as_main");
    if (runmodule == NULL) {
        pymain_error("Could not import runpy._run_module_as_main");
        goto error;
    }

    module = PyUnicode_FromWideChar(modname, -1);
    if (module == NULL) {
        pymain_error("Could not convert module name to unicode");
        goto error;
    }

    runargs = _PyTuple_FromPair(module, set_argv0 ? Py_True : Py_False);
    if (runargs == NULL) {
        pymain_error("Could not create arguments "
                     "for runpy._run_module_as_main");
        goto error;
    }

    result = PyObject_Call(runmodule, runargs, NULL);
    if (result == NULL) {
        goto error;
    }

done:
    Py_XDECREF(module);
    Py_XDECREF(runmodule);
    Py_XDECREF(runargs);
    Py_XDECREF(result);
    return exitcode;

error:
    exitcode = pymain_exit_err_print();
    goto done;
}


static int
pymain_run_file_obj(PyObject *filename, int skip_source_first_line)
{
    if (PySys_Audit("cpython.run_file", "O", filename) < 0) {
        return pymain_exit_err_print();
    }

    FILE *fp = Py_fopen(filename, "rb");
    if (fp == NULL) {
        pymain_error_format("can't open file %R:", filename);
        pymain_exit_err_print();
        return 2;
    }

    if (skip_source_first_line) {
        int ch;
        /* Push back first newline so line numbers remain the same */
        while ((ch = getc(fp)) != EOF) {
            if (ch == '\n') {
                (void)ungetc(ch, fp);
                break;
            }
        }
    }

    struct _Py_stat_struct sb;
    if (_Py_fstat_noraise(fileno(fp), &sb) == 0 && S_ISDIR(sb.st_mode)) {
        pymain_error_format("%R is a directory, cannot continue",
                            filename);
        fclose(fp);
        return 1;
    }

    if (pymain_check_signals() < 0) {
        fclose(fp);
        return pymain_exit_err_print();
    }

    /* _PyRun_AnyFile(closeit=1) calls fclose(fp) before running code */
    PyCompilerFlags cf = _PyCompilerFlags_INIT;
    PyObject *result = _PyRun_AnyFile(fp, filename, 1, &cf);
    if (result == NULL) {
        return pymain_exit_err_print();
    }
    Py_DECREF(result);
    return 0;
}

static int
pymain_run_file(const PyConfig *config)
{
    PyObject *filename = PyUnicode_FromWideChar(config->run_filename, -1);
    if (filename == NULL) {
        return pymain_exit_err_print();
    }

    int exitcode = pymain_run_file_obj(filename, config->skip_source_first_line);
    Py_XDECREF(filename);
    return exitcode;
}


static int
pymain_run_startup(PyConfig *config, int *exitcode)
{
    int ret = 0;
    PyObject *startup = NULL;

    if (!config->use_environment) {
        goto done;
    }
#ifdef MS_WINDOWS
    const wchar_t *env = _wgetenv(L"PYTHONSTARTUP");
    if (env == NULL || env[0] == L'\0') {
        goto done;
    }

    startup = PyUnicode_FromWideChar(env, -1);
    if (startup == NULL) {
        goto error;
    }
#else
    const char *env = _Py_GetEnv(config->use_environment, "PYTHONSTARTUP");
    if (env == NULL) {
        goto done;
    }

    startup = PyUnicode_DecodeFSDefault(env);
    if (startup == NULL) {
        goto error;
    }
#endif
    if (PySys_Audit("cpython.run_startup", "O", startup) < 0) {
        goto error;
    }

    FILE *fp = Py_fopen(startup, "r");
    if (fp == NULL) {
        pymain_error("Could not open PYTHONSTARTUP");
        goto error;
    }

    PyCompilerFlags cf = _PyCompilerFlags_INIT;
    PyObject *result = _PyRun_SimpleFile(fp, startup, 0, &cf);
    fclose(fp);
    if (result == NULL) {
        goto error;
    }
    Py_DECREF(result);

done:
    Py_XDECREF(startup);
    return ret;

error:
    ret = pymain_err_print(exitcode);
    goto done;
}


/* Write an exitcode into *exitcode and return 1 if we have to exit Python.
   Return 0 otherwise. */
static int
pymain_run_interactive_hook(int *exitcode)
{
    PyObject *hook;
    if (PySys_GetOptionalAttrString("__interactivehook__", &hook) < 0) {
        goto error;
    }
    if (hook == NULL) {
        return 0;
    }

    if (PySys_Audit("cpython.run_interactivehook", "O", hook) < 0) {
        Py_DECREF(hook);
        goto error;
    }

    PyObject *result = _PyObject_CallNoArgs(hook);
    Py_DECREF(hook);
    if (result == NULL) {
        goto error;
    }
    Py_DECREF(result);
    return 0;

error:
    pymain_error("Failed calling sys.__interactivehook__:");
    return pymain_err_print(exitcode);
}


static int
pymain_set_inspect(PyConfig *config, int inspect, int *exitcode)
{
    PyObject *value = PyLong_FromLong(inspect);
    if (value == NULL || PyConfig_Set("inspect", value) < 0) {
        Py_XDECREF(value);
        pymain_error("Could not set the inspect flag");
        return pymain_err_print(exitcode);
    }
    else {
        assert(config->inspect == inspect);
    }
    Py_XDECREF(value);
    return 0;
}


static int
_pymain_run_repl(PyConfig *config, int startup)
{
    if (pymain_check_signals() < 0) {
        goto error;
    }

    if (PySys_Audit("cpython.run_stdin", NULL) < 0) {
        goto error;
    }

    if (isatty(fileno(stdin))
        && !_Py_GetEnv(config->use_environment, "PYTHON_BASIC_REPL"))
    {
        PyObject *pyrepl = PyImport_ImportModule("_pyrepl");
        if (pyrepl != NULL) {
            int exitcode = pymain_run_pyrepl(startup);
            Py_DECREF(pyrepl);
            return exitcode;
        }

        if (!PyErr_ExceptionMatches(PyExc_ModuleNotFoundError)) {
            pymain_error("Could not import _pyrepl.main");
            goto error;
        }
        PyErr_Clear();
    }

    PyCompilerFlags cf = _PyCompilerFlags_INIT;
    PyObject *result = NULL;
    PyObject *stdin_obj = PyUnicode_FromString("<stdin>");
    if (stdin_obj != NULL) {
        result = _PyRun_AnyFile(stdin, stdin_obj, 0, &cf);
        Py_DECREF(stdin_obj);
    }
    if (result == NULL) {
        goto error;
    }
    Py_DECREF(result);
    return 0;

error:
    return pymain_exit_err_print();
}

static int
pymain_run_stdin(PyConfig *config)
{
    if (stdin_is_interactive(config)) {
        // do exit on SystemExit
        int exitcode;
        if (pymain_set_inspect(config, 0, &exitcode)) {
            return exitcode;
        }

        if (pymain_run_startup(config, &exitcode)) {
            return exitcode;
        }

        if (pymain_run_interactive_hook(&exitcode)) {
            return exitcode;
        }
    }

    return _pymain_run_repl(config, 0);
}


static void
pymain_repl(PyConfig *config, int *exitcode)
{
    /* Check this environment variable at the end, to give programs the
       opportunity to set it from Python. */
    if (!config->inspect && _Py_GetEnv(config->use_environment, "PYTHONINSPECT")) {
        if (pymain_set_inspect(config, 1, exitcode)) {
            return;
        }
    }

    if (!(config->inspect && stdin_is_interactive(config) && config_run_code(config))) {
        return;
    }

    if (pymain_set_inspect(config, 0, exitcode)) {
        return;
    }
    if (pymain_run_interactive_hook(exitcode)) {
        return;
    }

    *exitcode = _pymain_run_repl(config, 1);
}


static int
pymain_set_path0(PyObject *main_importer_path)
{
    PyConfig *config = (PyConfig *)_Py_GetConfig();

    PyObject *path0 = NULL;
    if (main_importer_path != NULL) {
        path0 = Py_NewRef(main_importer_path);
    }
    else if (!config->safe_path) {
        int res = _PyPathConfig_ComputeSysPath0(&config->argv, &path0);
        if (res < 0) {
            return -1;
        }
        else if (res == 0) {
            Py_CLEAR(path0);
        }
    }

    if (path0 == NULL) {
        return 0;
    }

    // XXX Apply config->sys_path_0 in init_interp_main().  We have
    // to be sure to get readline/rlcompleter imported at the correct time.
    wchar_t *wstr = PyUnicode_AsWideCharString(path0, NULL);
    if (wstr == NULL) {
        goto error;
    }

    PyStatus status = PyConfig_SetString(config, &config->sys_path_0, wstr);
    PyMem_Free(wstr);
    if (_PyStatus_EXCEPTION(status)) {
        _PyErr_SetFromPyStatus(status);
        goto error;
    }

    int res = pymain_sys_path_add_path0(path0);
    Py_DECREF(path0);

    return res;

error:
    Py_DECREF(path0);
    return -1;
}


static void
pymain_run_python(int *exitcode)
{
    PyInterpreterState *interp = _PyInterpreterState_GET();
    /* pymain_repl() and pymain_run_stdin() modify the config */
    PyConfig *config = (PyConfig*)_PyInterpreterState_GetConfig(interp);

    // Process command line options which want to exit Python
    int cmdline_exitcode = _PyConfig_ProcessDeferredCmdlineOption(config);
    if (cmdline_exitcode >= 0) {
        *exitcode = cmdline_exitcode;
        return;
    }

    int set_running_main = 0;

    PyObject *main_importer_path = NULL;

    /* ensure path config is written into global variables */
    PyStatus status = _PyPathConfig_UpdateGlobal(config);
    if (_PyStatus_EXCEPTION(status)) {
        _PyErr_SetFromPyStatus(status);
        goto error;
    }

    // XXX Calculate config->sys_path_0 in getpath.py.
    // The tricky part is that we can't check the path importers yet
    // at that point.
    assert(config->sys_path_0 == NULL);

    if (pymain_get_importer(config, &main_importer_path, exitcode)) {
        return;
    }

    // import readline and rlcompleter before script dir is added to sys.path
    if (pymain_import_readline(config) < 0) {
        goto error;
    }

    if (pymain_set_path0(main_importer_path) < 0) {
        goto error;
    }

    pymain_header(config);

    _PyInterpreterState_SetRunningMain(interp);
    set_running_main = 1;
    assert(!PyErr_Occurred());

    if (pymain_check_signals() < 0) {
        goto error;
    }

    if (config->run_command) {
        *exitcode = pymain_run_command(config->run_command);
    }
    else if (config->run_module) {
        *exitcode = pymain_run_module(config->run_module, 1);
    }
    else if (main_importer_path != NULL) {
        *exitcode = pymain_run_module(L"__main__", 0);
    }
    else if (config->run_filename != NULL) {
        *exitcode = pymain_run_file(config);
    }
    else {
        *exitcode = pymain_run_stdin(config);
    }

    if (pymain_check_signals() < 0) {
        goto error;
    }

    pymain_repl(config, exitcode);
    goto done;

error:
    *exitcode = pymain_exit_err_print();

done:
    if (set_running_main) {
        _PyInterpreterState_SetNotRunningMain(interp);
    }
    Py_XDECREF(main_importer_path);
}


/* --- pymain_main() ---------------------------------------------- */

static void
pymain_free(void)
{
    _PyImport_Fini2();

    /* Free global variables which cannot be freed in Py_Finalize():
       configuration options set before Py_Initialize() which should
       remain valid after Py_Finalize(), since
       Py_Initialize()-Py_Finalize() can be called multiple times. */
    _PyPathConfig_ClearGlobal();
    _Py_ClearArgcArgv();
    _PyRuntime_Finalize();
    _Py_GetVersion_Fini();
}


static int
exit_sigint(void)
{
    /* bpo-1054041: We need to exit via the
     * SIG_DFL handler for SIGINT if KeyboardInterrupt went unhandled.
     * If we don't, a calling process such as a shell may not know
     * about the user's ^C.  https://www.cons.org/cracauer/sigint.html */
#if defined(HAVE_GETPID) && defined(HAVE_KILL) && !defined(MS_WINDOWS)
    if (PyOS_setsig(SIGINT, SIG_DFL) == SIG_ERR) {
        perror("signal");  /* Impossible in normal environments. */
    } else {
        kill(getpid(), SIGINT);
    }
    /* If setting SIG_DFL failed, or kill failed to terminate us,
     * there isn't much else we can do aside from an error code. */
#endif  /* HAVE_GETPID && !MS_WINDOWS */
#ifdef MS_WINDOWS
    /* cmd.exe detects this, prints ^C, and offers to terminate. */
    /* https://msdn.microsoft.com/en-us/library/cc704588.aspx */
    return STATUS_CONTROL_C_EXIT;
#else
    return SIGINT + 128;
#endif  /* !MS_WINDOWS */
}


static void _Py_NO_RETURN
pymain_exit_error(PyStatus status)
{
    if (_PyStatus_IS_EXIT(status)) {
        /* If it's an error rather than a regular exit, leave Python runtime
           alive: Py_ExitStatusException() uses the current exception and use
           sys.stdout in this case. */
        pymain_free();
    }
    Py_ExitStatusException(status);
}


int
Py_RunMain(void)
{
    int exitcode = 0;

    _PyRuntime.signals.unhandled_keyboard_interrupt = 0;

    pymain_run_python(&exitcode);

    if (Py_FinalizeEx() < 0) {
        /* Value unlikely to be confused with a non-error exit status or
           other special meaning */
        exitcode = 120;
    }

    pymain_free();

    if (_PyRuntime.signals.unhandled_keyboard_interrupt) {
        exitcode = exit_sigint();
    }

    return exitcode;
}


static int
pymain_main(_PyArgv *args)
{
    PyStatus status = pymain_init(args);
    assert(!_PyStatus_IS_EXIT(status));
    if (_PyStatus_EXCEPTION(status)) {
        pymain_exit_error(status);
    }

    return Py_RunMain();
}


int
Py_Main(int argc, wchar_t **argv)
{
    _PyArgv args = {
        .argc = argc,
        .use_bytes_argv = 0,
        .bytes_argv = NULL,
        .wchar_argv = argv};
    return pymain_main(&args);
}


int
Py_BytesMain(int argc, char **argv)
{
    _PyArgv args = {
        .argc = argc,
        .use_bytes_argv = 1,
        .bytes_argv = argv,
        .wchar_argv = NULL};
    return pymain_main(&args);
}
