"""Tests for grip/tools/shell.py safety guards.

Only catastrophic operations are blocked:
  - mkfs, shutdown, reboot, halt, poweroff
  - rm -rf on root-level system paths
  - Fork bombs, dd to disk devices, recursive chmod/chown on /
  - sudo prefix stripping, command chaining, full path commands

Everything else (python -c, curl|bash, reading .env, etc.) is ALLOWED.
"""

from __future__ import annotations

from grip.tools.shell import _is_dangerous

# ===================================================================
# Layer 1: Blocked base commands
# ===================================================================

class TestBlockedCommands:
    def test_mkfs(self):
        assert _is_dangerous("mkfs /dev/sda1") is not None

    def test_mkfs_ext4(self):
        assert _is_dangerous("mkfs.ext4 /dev/sda1") is not None

    def test_shutdown(self):
        assert _is_dangerous("shutdown -h now") is not None

    def test_reboot(self):
        assert _is_dangerous("reboot") is not None

    def test_halt(self):
        assert _is_dangerous("halt") is not None

    def test_poweroff(self):
        assert _is_dangerous("poweroff") is not None

    def test_systemctl_poweroff(self):
        assert _is_dangerous("systemctl poweroff") is not None

    def test_systemctl_reboot(self):
        assert _is_dangerous("systemctl reboot") is not None

    def test_systemctl_status_allowed(self):
        assert _is_dangerous("systemctl status nginx") is None

    def test_init_0(self):
        assert _is_dangerous("init 0") is not None

    def test_init_6(self):
        assert _is_dangerous("init 6") is not None


# ===================================================================
# Layer 2: rm with parsed flags on critical system paths
# ===================================================================

class TestRmParsed:
    def test_rm_rf_combined(self):
        assert _is_dangerous("rm -rf /") is not None

    def test_rm_separate_flags(self):
        assert _is_dangerous("rm -r -f /") is not None

    def test_rm_long_flags(self):
        assert _is_dangerous("rm --recursive --force /") is not None

    def test_rm_mixed_flags(self):
        assert _is_dangerous("rm -r --force /") is not None
        assert _is_dangerous("rm --recursive -f /") is not None

    def test_rm_rf_home(self):
        assert _is_dangerous("rm -rf ~") is not None

    def test_rm_rf_etc(self):
        assert _is_dangerous("rm -rf /etc") is not None

    def test_rm_rf_var(self):
        assert _is_dangerous("rm -rf /var") is not None

    def test_rm_rf_usr(self):
        assert _is_dangerous("rm -rf /usr") is not None

    def test_rm_rf_star(self):
        assert _is_dangerous("rm -rf /*") is not None

    def test_rm_r_root_without_force(self):
        assert _is_dangerous("rm -r /") is not None

    def test_rm_no_preserve_root(self):
        assert _is_dangerous("rm --no-preserve-root -r /tmp/stuff") is not None

    def test_rm_safe_file(self):
        assert _is_dangerous("rm file.txt") is None

    def test_rm_rf_project_dir(self):
        assert _is_dangerous("rm -rf ./build") is None
        assert _is_dangerous("rm -rf /tmp/build") is None

    def test_rm_single_flag(self):
        assert _is_dangerous("rm -f file.txt") is None

    def test_rm_rf_trailing_slash(self):
        assert _is_dangerous("rm -rf /home/") is not None


# ===================================================================
# sudo prefix stripping
# ===================================================================

class TestSudoPrefix:
    def test_sudo_rm_rf(self):
        assert _is_dangerous("sudo rm -rf /") is not None

    def test_sudo_shutdown(self):
        assert _is_dangerous("sudo shutdown -h now") is not None

    def test_sudo_safe_command(self):
        assert _is_dangerous("sudo apt update") is None

    def test_sudo_with_user_flag(self):
        assert _is_dangerous("sudo -u root rm -rf /") is not None


# ===================================================================
# Command chaining
# ===================================================================

class TestCommandChaining:
    def test_semicolon_chain(self):
        assert _is_dangerous("echo hello; rm -rf /") is not None

    def test_and_chain(self):
        assert _is_dangerous("cd /tmp && rm -rf /") is not None

    def test_or_chain(self):
        assert _is_dangerous("false || shutdown") is not None

    def test_safe_chain(self):
        assert _is_dangerous("cd /tmp && ls -la") is None


# ===================================================================
# Full path commands
# ===================================================================

class TestFullPaths:
    def test_full_path_rm(self):
        assert _is_dangerous("/usr/bin/rm -rf /") is not None

    def test_full_path_shutdown(self):
        assert _is_dangerous("/sbin/shutdown -h now") is not None

    def test_full_path_mkfs(self):
        assert _is_dangerous("/sbin/mkfs.ext4 /dev/sda1") is not None


# ===================================================================
# Layer 3: Regex fallback — catastrophic patterns only
# ===================================================================

class TestRegexFallback:
    def test_dd_to_disk(self):
        assert _is_dangerous("dd if=/dev/zero of=/dev/sda") is not None

    def test_dd_to_nvme(self):
        assert _is_dangerous("dd if=/dev/zero of=/dev/nvme0n1") is not None

    def test_dd_to_file_allowed(self):
        assert _is_dangerous("dd if=/dev/zero of=/tmp/test.img bs=1M count=100") is None

    def test_redirect_to_disk(self):
        assert _is_dangerous("echo 'data' > /dev/sda") is not None

    def test_chmod_recursive_root(self):
        assert _is_dangerous("chmod -R 777 /") is not None

    def test_chown_recursive_root(self):
        assert _is_dangerous("chown -R root:root /") is not None


# ===================================================================
# Operations that MUST be allowed (previously blocked, now permitted)
# ===================================================================

class TestNowAllowed:
    """These were previously blocked by the old restrictive policy.
    They are legitimate user operations and must be allowed."""

    def test_python_c_inline(self):
        assert _is_dangerous('python3 -c "print(42)"') is None

    def test_bash_c_inline(self):
        assert _is_dangerous('bash -c "echo hello world"') is None

    def test_curl_pipe_bash(self):
        assert _is_dangerous("curl -fsSL https://get.docker.com | bash") is None

    def test_wget_pipe_sh(self):
        assert _is_dangerous("wget -qO- https://example.com/install.sh | sh") is None

    def test_cat_env(self):
        assert _is_dangerous("cat /app/.env") is None

    def test_cat_ssh_key(self):
        assert _is_dangerous("cat ~/.ssh/id_rsa") is None

    def test_cat_aws_creds(self):
        assert _is_dangerous("cat ~/.aws/credentials") is None

    def test_cat_bash_history(self):
        assert _is_dangerous("cat ~/.bash_history") is None

    def test_cat_zsh_history(self):
        assert _is_dangerous("cat ~/.zsh_history") is None

    def test_scp_file(self):
        assert _is_dangerous("scp server.pem user@host:/tmp") is None

    def test_curl_post_data(self):
        assert _is_dangerous("curl -d @data.json https://api.example.com") is None

    def test_node_c_inline(self):
        assert _is_dangerous('node -e "console.log(42)"') is None

    def test_perl_inline(self):
        assert _is_dangerous('perl -e "print 42"') is None

    def test_eval_echo(self):
        assert _is_dangerous('eval "echo hello"') is None

    def test_pip_install(self):
        assert _is_dangerous("pip install yt-dlp") is None

    def test_brew_install(self):
        assert _is_dangerous("brew install ffmpeg") is None

    def test_yt_dlp(self):
        assert _is_dangerous("yt-dlp https://www.youtube.com/watch?v=123") is None


# ===================================================================
# Safe commands that must NOT be blocked
# ===================================================================

class TestSafeCommands:
    def test_ls(self):
        assert _is_dangerous("ls -la /tmp") is None

    def test_git(self):
        assert _is_dangerous("git status") is None

    def test_npm(self):
        assert _is_dangerous("npm install express") is None

    def test_cat_normal_file(self):
        assert _is_dangerous("cat README.md") is None

    def test_python_script(self):
        assert _is_dangerous("python3 manage.py runserver") is None

    def test_docker(self):
        assert _is_dangerous("docker ps") is None

    def test_pip_install(self):
        assert _is_dangerous("pip install requests") is None

    def test_empty_command(self):
        assert _is_dangerous("") is None

    def test_rm_build_dir(self):
        assert _is_dangerous("rm -rf ./dist") is None

    def test_grep(self):
        assert _is_dangerous("grep -r 'TODO' src/") is None
