/* 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)
{
    int set_running_main = 0;

    PyObject *main_importer_path = NULL;
    PyInterpreterState *interp = _PyInterpreterState_GET();
    /* pymain_repl() and pymain_run_stdin() modify the config */
    PyConfig *config = (PyConfig*)_PyInterpreterState_GetConfig(interp);

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


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);
    if (_PyStatus_IS_EXIT(status)) {
        pymain_free();
        return status.exitcode;
    }
    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);
}
