#!/usr/bin/env python3
# runner
# Located in the top-level <svr pmemstat> directory
#
# Developer convenience wrapper for exercising the *working source tree*
# (rather than an installed copy of pmemstat).
#
# The pinned dependencies live in the project virtualenv (./.venv, PEP 668
# friendly, nothing installed per-user or system-wide).  This script re-execs
# itself with that interpreter when it was started with another one.
#
# Like the installed tool, this script runs as root by default (re-exec'ing
# itself via sudo), so that every process is visible.  Pass -U/--user to opt
# out and stay as the invoking user instead.

import os
import sys

# Add the project directory to sys.path for editable install support.  This
# must stay ahead of any installed copy so that "from pmemstat import main"
# always loads the source under test, never a pip-installed release.
project_dir = os.path.dirname(os.path.abspath(__file__))
if project_dir not in sys.path:
    sys.path.insert(0, project_dir)

venv_dir = os.path.join(project_dir, '.venv')
venv_python = os.path.join(venv_dir, 'bin', 'python')


def running_in_project_venv():
    """True if this process already runs on the project's ``.venv`` interpreter.

    The test is on ``sys.prefix`` (the venv root), never on the executable
    path: ``.venv/bin/python`` is a symlink to the system interpreter, so
    ``realpath(sys.executable)`` is identical both inside and outside the venv
    and would wrongly report "already in the venv".
    """
    return os.path.realpath(sys.prefix) == os.path.realpath(venv_dir)


def re_exec_in_project_venv():
    """Re-exec this script with ``./.venv/bin/python`` when it exists.

    ``#!/usr/bin/env python3`` may resolve to a system interpreter that does
    not have the pinned ``console-window`` dependency.  Re-exec'ing into the
    project venv keeps ``./runner`` working no matter which interpreter the
    developer's shell picks, and it means the later sudo elevation hands root
    the same ``.venv/bin/python`` -- so root imports the pinned dependency from
    the venv (which root can read) instead of a per-user site-packages
    directory that root does not search.

    This is a developer convenience only: the installed ``pmemstat`` entry
    point never does this, and its sudo elevation path deliberately refuses to
    inject a user-writable import path into root.

    On success the process image is replaced and this function never returns.
    If the venv is missing or cannot be executed, the current interpreter is
    used unchanged.
    """
    if running_in_project_venv():
        return
    if not os.access(venv_python, os.X_OK):
        return
    try:
        os.execv(venv_python,
                 [venv_python, os.path.abspath(__file__)] + sys.argv[1:])
    except OSError as exc:
        print(f'pmemstat: could not re-exec in {venv_python}: {exc}; '
              'continuing with the current interpreter', file=sys.stderr)


def user_mode_requested(args):
    """True if ``-U``/``--user`` was given (user mode: do NOT elevate).

    Also recognizes ``-U`` inside a bundled short-option cluster such as
    ``-UD``; ``U`` is the only short option that selects user mode.
    """
    return any(
        arg == '--user'
        or (arg.startswith('-') and not arg.startswith('--') and 'U' in arg)
        for arg in args
    )


def maybe_elevate():
    """Re-exec this script as root via sudo unless user mode was requested.

    Running the working tree as root shows every process.  Elevating through
    this wrapper (instead of letting ``pmemstat`` re-exec an isolated
    interpreter) runs the project's own ``.venv/bin/python`` (see
    :func:`re_exec_in_project_venv`), so both the source under test and its
    pinned dependency are the ones that run.

    On success the process is replaced and this function never returns.  If
    ``sudo`` cannot be executed at all, it exits fatally: root is the default
    view, so a silent downgrade would hide that the data is partial.  Pass
    ``-U``/``--user`` to request the user-only run explicitly.
    """
    if os.geteuid() == 0:
        return
    args = sys.argv[1:]
    if user_mode_requested(args):
        return
    cmd = ['sudo']
    # sudo resets the environment, so re-assert PMEMSTAT_ARGS (if any) on the
    # command line; otherwise a persistent option set there would be lost.
    pmemstat_args = os.environ.get('PMEMSTAT_ARGS')
    if pmemstat_args:
        cmd.append('PMEMSTAT_ARGS=' + pmemstat_args)
    cmd += [sys.executable, os.path.abspath(__file__)] + args
    try:
        os.execvp('sudo', cmd)
    except OSError as exc:
        print(f'pmemstat: FATAL: could not elevate to root via sudo: {exc}; '
              'run as root or pass -U/--user for the user-only view.',
              file=sys.stderr)
        sys.exit(1)


re_exec_in_project_venv()
maybe_elevate()

# Import and run the main module directly
if __name__ == '__main__':
    sys.argv[0] = 'pmemstat'
    from pmemstat import main
    main.run()
