"""R integration recipe for Dataiku DSS.

Provides reusable steps for installing R dependencies (via Dataiku's own
`install-deps.sh -with-r`) and enabling R integration with
`dssadmin install-R-integration` on an existing DSS instance.

Used by:
- `k4s install dataiku --with-r`
- `k4s install r` (post-install enablement)
"""

from __future__ import annotations

import os
import subprocess
import tempfile

from k4s.core.executor import Executor
from k4s.core.products import Step
from k4s.recipes.common.run import check, q, run
from k4s.ui.ui import Ui


def build_r_steps(
    ui: Ui,
    ex: Executor,
    *,
    extracted_dir: str,
    data_dir: str,
    os_user: str,
    r_repo: str | None = None,
    r_pkg_dir: str | None = None,
) -> list[Step]:
    """Build steps to install R integration on an existing Dataiku DSS instance."""

    def _install_r_deps():
        ui.log("Installing OS-level R packages via Dataiku's install-deps.sh (with -with-r).")
        check(
            ex,
            f"sudo -n DEBIAN_FRONTEND=noninteractive "
            f"{q(extracted_dir)}/scripts/install/install-deps.sh -yes "
            f"-without-java -without-python -with-r",
        )

    def _install_r_integration():
        ui.log("Running dssadmin install-R-integration. DSS is stopped/restarted automatically.")
        run(ex, f"sudo -n -u {q(os_user)} -i -- sh -c {q(f'{data_dir}/bin/dss stop')}")

        r_cmd = f"{data_dir}/bin/dssadmin install-R-integration"
        if r_pkg_dir:
            remote_pkg_dir = "/tmp/k4s-r-packages"
            _upload_pkg_dir(ex, r_pkg_dir, remote_pkg_dir, os_user)
            r_cmd += f" -pkgDir {remote_pkg_dir}"
        elif r_repo:
            r_cmd += f" -repo {r_repo}"

        check(
            ex,
            f"sudo -n -u {q(os_user)} -i -- sh -c {q(r_cmd)}",
        )

        run(ex, f"sudo -n -u {q(os_user)} -i -- sh -c {q(f'{data_dir}/bin/dss start')}")

    return [
        Step(title="Install R dependencies", run=_install_r_deps),
        Step(title="Install R integration", run=_install_r_integration),
    ]


def _upload_pkg_dir(ex: Executor, local_dir: str, remote_dir: str, os_user: str) -> None:
    """Tar a local directory, upload, and extract on the remote host."""
    with tempfile.NamedTemporaryFile(suffix=".tar.gz", delete=True) as tmp:
        tmp_path = tmp.name

    subprocess.check_call(
        ["tar", "czf", tmp_path, "-C", local_dir, "."],
    )
    try:
        remote_tar = "/tmp/k4s-r-packages.tar.gz"
        ex.upload_file(tmp_path, remote_tar, use_sudo=True)
        check(ex, f"sudo -n mkdir -p {q(remote_dir)}")
        check(ex, f"sudo -n tar xzf {q(remote_tar)} -C {q(remote_dir)}")
        check(ex, f"sudo -n chown -R {q(os_user)} {q(remote_dir)}")
        run(ex, f"sudo -n rm -f {q(remote_tar)}")
    finally:
        if os.path.exists(tmp_path):
            os.unlink(tmp_path)

