"""Automatically activate, and deactivate virutal environments."""

import itertools
import os
import pathlib

VENVER_FILE = ".venver"


def generate_command() -> str:
    """Return the command to activate, or deactivate a virutal environment.

    The path to the environment to activate must be the first line of a
    ``.venver`` file, or the file may be empty, in which case the default path,
    ``./.venv``, will be used. The default path may be overridden by the
    ``VENVER_DEFAULT_VENV`` environment variable. The command to activate the
    environment identified by the file will be returned whenever entering the
    directory containing this file, or any descendant directory.

    The command to deactivate the environment will be returned whenever
    navigating outside of the ``.venver`` directory.

    If the environment is manually deactivated, an activate command will not be
    returned, unless you navigate outside the ``.venver`` directory, then
    reenter it.

    Usually, the environment is located in the same directory as the
    ``.venver`` file. However, you may specify an environment path outside of
    the ``.venver`` directory. In this case commands will still be returned
    based on navigation relative to the ``.venver`` directory, and not the
    environment directory.
    """
    venver_root = os.getenv("VENVER_ROOT")
    cwd = pathlib.Path.cwd()
    cmd = ""

    if venver_root:
        if cwd.is_relative_to(pathlib.Path(venver_root)):
            return cmd
        cmd = "unset VENVER_ROOT;command -v deactivate 1 > /dev/null && deactivate || true;"

    default_venv = os.getenv("VENVER_DEFAULT_VENV", "./.venv")
    for cur in itertools.chain((cwd,), cwd.parents):
        maybe_venver = cur / VENVER_FILE
        if maybe_venver.exists():
            with maybe_venver.open() as f:
                maybe_venv = pathlib.Path(f.readline().strip() or default_venv)
                maybe_venv_full = (
                    maybe_venv if maybe_venv.is_absolute() else cur.joinpath(maybe_venv)
                )
                maybe_venv_activate = maybe_venv_full / "bin" / "activate"
                if maybe_venv_activate.exists():
                    return f"{cmd}export VENVER_ROOT='{cur}';source {maybe_venv_activate};"

    return cmd


def cli() -> int:  # pragma: no cover
    """Print an :func:`auto` command to ``stdout``."""
    print(generate_command())  # noqa: T201
    return 0
