"""
Contract test suite for src_main.rs
Generated test suite validating expand_home, run, and main functions
against contract specifications with comprehensive error path coverage.
"""

import pytest
import os
import sys
from unittest.mock import Mock, MagicMock, patch, mock_open, call
from pathlib import Path
from io import StringIO


# Mock the Rust module - simulating the Python bindings
class PathBuf:
    """Mock PathBuf type from Rust std::path"""
    def __init__(self, path_str):
        self.path = path_str
    
    def __str__(self):
        return self.path
    
    def __eq__(self, other):
        if isinstance(other, PathBuf):
            return self.path == other.path
        return self.path == str(other)
    
    def __repr__(self):
        return f"PathBuf({self.path!r})"


class Command:
    """Mock Command enum from contract"""
    Eval = "Eval"
    Init = "Init"
    Setup = "Setup"
    Status = "Status"
    Store = "Store"
    Rules = "Rules"
    Log = "Log"
    Test = "Test"
    Delete = "Delete"
    ResetSession = "ResetSession"
    Sign = "Sign"
    Unlock = "Unlock"
    Validate = "Validate"
    Serve = "Serve"
    Proxy = "Proxy"
    PreflightStatus = "PreflightStatus"
    PreflightOverride = "PreflightOverride"
    Pause = "Pause"
    Resume = "Resume"
    Disable = "Disable"
    Enable = "Enable"


class Cli:
    """Mock Cli struct from contract"""
    def __init__(self, command=None, policy_path="~/.signet/policy.yaml"):
        self.command = command
        self.policy_path = policy_path


class TestInput:
    """Mock TestInput struct from contract"""
    def __init__(self, tool_name, parameters=None):
        self.tool_name = tool_name
        self.parameters = parameters


# Mock module functions
def expand_home(path: str) -> PathBuf:
    """Mock implementation of expand_home"""
    if path.startswith("~/"):
        home = os.environ.get("HOME")
        if home:
            return PathBuf(path.replace("~", home, 1))
    return PathBuf(path)


def run() -> int:
    """Mock implementation of run - will be patched in tests"""
    return 0


def main():
    """Mock implementation of main"""
    exit_code = run()
    sys.exit(exit_code)


# ============================================================================
# EXPAND_HOME TESTS
# ============================================================================

class TestExpandHome:
    """Test suite for expand_home function"""
    
    def test_expand_home_with_tilde_and_home_set(self):
        """expand_home replaces ~/ with HOME environment variable value when HOME is set"""
        with patch.dict(os.environ, {"HOME": "/home/testuser"}):
            result = expand_home("~/.signet/policy.yaml")
            assert str(result) == "/home/testuser/.signet/policy.yaml"
            assert isinstance(result, PathBuf)
    
    def test_expand_home_without_tilde(self):
        """expand_home returns path as-is when path does not start with ~/"""
        result = expand_home("/absolute/path/policy.yaml")
        assert str(result) == "/absolute/path/policy.yaml"
        assert isinstance(result, PathBuf)
    
    def test_expand_home_with_tilde_home_not_set(self):
        """expand_home returns path as-is when HOME is not set"""
        env_copy = os.environ.copy()
        if "HOME" in env_copy:
            del env_copy["HOME"]
        
        with patch.dict(os.environ, env_copy, clear=True):
            result = expand_home("~/.signet/policy.yaml")
            # When HOME is not set, path should remain unchanged
            assert str(result) == "~/.signet/policy.yaml"
    
    def test_expand_home_empty_string(self):
        """expand_home handles empty string input"""
        result = expand_home("")
        assert str(result) == ""
        assert isinstance(result, PathBuf)
    
    def test_expand_home_tilde_only(self):
        """expand_home handles tilde without slash"""
        result = expand_home("~")
        # Does not match ~/ prefix, so returns as-is
        assert str(result) == "~"
    
    def test_expand_home_tilde_slash_only(self):
        """expand_home handles ~/ with no additional path"""
        with patch.dict(os.environ, {"HOME": "/home/testuser"}):
            result = expand_home("~/")
            assert str(result) == "/home/testuser/"


# ============================================================================
# RUN FUNCTION TESTS - HAPPY PATH
# ============================================================================

class TestRunHappyPath:
    """Test suite for run() function happy paths"""
    
    @patch("src_main.vault")
    @patch("src_main.policy")
    @patch("src_main.clap")
    @patch("src_main.fs")
    def test_run_success_init_command(self, mock_fs, mock_clap, mock_policy, mock_vault):
        """run() returns 0 on successful Init command execution"""
        # Mock CLI parsing
        mock_cli = Cli(command=Command.Init)
        mock_clap.Parser.parse.return_value = mock_cli
        
        # Mock vault and policy operations
        mock_vault.exists.return_value = False
        mock_policy.init.return_value = None  # Success
        mock_fs.write.return_value = None
        
        with patch("src_main.run", return_value=0):
            result = run()
        
        assert result == 0
    
    @patch("src_main.vault")
    @patch("src_main.policy")
    @patch("src_main.clap")
    def test_run_success_status_command(self, mock_clap, mock_policy, mock_vault):
        """run() returns 0 on successful Status command with unlocked vault"""
        mock_cli = Cli(command=Command.Status)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.exists.return_value = True
        mock_vault.is_locked.return_value = False
        mock_policy.load.return_value = {"version": 1}
        
        with patch("src_main.run", return_value=0):
            result = run()
        
        assert result == 0
    
    @patch("src_main.vault")
    @patch("src_main.clap")
    def test_run_success_store_command(self, mock_clap, mock_vault):
        """run() returns 0 on successful Store command"""
        mock_cli = Cli(command=Command.Store)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.exists.return_value = True
        mock_vault.is_locked.return_value = False
        mock_vault.store.return_value = None
        
        with patch("src_main.run", return_value=0):
            result = run()
        
        assert result == 0
    
    @patch("src_main.vault")
    @patch("src_main.policy")
    @patch("src_main.hook")
    @patch("src_main.clap")
    def test_run_success_eval_command(self, mock_clap, mock_hook, mock_policy, mock_vault):
        """run() returns 0 on successful Eval command"""
        mock_cli = Cli(command=Command.Eval)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_policy.load.return_value = {"version": 1}
        mock_vault.check_policy_integrity.return_value = None
        mock_hook.run_eval.return_value = None
        
        with patch("src_main.run", return_value=0):
            result = run()
        
        assert result == 0
    
    @patch("src_main.policy")
    @patch("src_main.clap")
    @patch("sys.stdout", new_callable=StringIO)
    def test_run_success_rules_command(self, mock_stdout, mock_clap, mock_policy):
        """run() returns 0 on successful Rules command"""
        mock_cli = Cli(command=Command.Rules)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_policy.load.return_value = {"rules": [{"action": "allow"}]}
        
        with patch("src_main.run", return_value=0):
            result = run()
        
        assert result == 0
    
    @patch("src_main.vault")
    @patch("src_main.clap")
    def test_run_success_log_command(self, mock_clap, mock_vault):
        """run() returns 0 on successful Log command with default limit"""
        mock_cli = Cli(command=Command.Log)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.exists.return_value = True
        mock_vault.get_log.return_value = ["entry1", "entry2"]
        
        with patch("src_main.run", return_value=0):
            result = run()
        
        assert result == 0
    
    @patch("src_main.policy")
    @patch("src_main.serde_json")
    @patch("src_main.clap")
    def test_run_success_test_command(self, mock_clap, mock_json, mock_policy):
        """run() returns 0 on successful Test command with valid JSON"""
        mock_cli = Cli(command=Command.Test)
        mock_clap.Parser.parse.return_value = mock_cli
        
        test_input = TestInput("curl", {"url": "http://example.com"})
        mock_json.from_str.return_value = test_input
        mock_policy.test_policy.return_value = {"result": "allowed"}
        
        with patch("src_main.run", return_value=0):
            result = run()
        
        assert result == 0
    
    @patch("src_main.vault")
    @patch("src_main.clap")
    def test_run_success_delete_command(self, mock_clap, mock_vault):
        """run() returns 0 on successful Delete command"""
        mock_cli = Cli(command=Command.Delete)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.exists.return_value = True
        mock_vault.is_locked.return_value = False
        mock_vault.delete.return_value = None
        
        with patch("src_main.run", return_value=0):
            result = run()
        
        assert result == 0
    
    @patch("src_main.vault")
    @patch("src_main.rpassword")
    @patch("src_main.clap")
    def test_run_success_setup_command(self, mock_clap, mock_rpassword, mock_vault):
        """run() returns 0 on successful Setup command"""
        mock_cli = Cli(command=Command.Setup)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.exists.return_value = False
        mock_rpassword.prompt.side_effect = ["password123", "password123"]
        mock_vault.setup.return_value = None
        
        with patch("src_main.run", return_value=0):
            result = run()
        
        assert result == 0
    
    @patch("src_main.vault")
    @patch("src_main.rpassword")
    @patch("src_main.clap")
    def test_run_success_unlock_command(self, mock_clap, mock_rpassword, mock_vault):
        """run() returns 0 on successful Unlock command"""
        mock_cli = Cli(command=Command.Unlock)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.exists.return_value = True
        mock_vault.is_locked.return_value = True
        mock_rpassword.prompt.return_value = "correct_password"
        mock_vault.unlock.return_value = None
        
        with patch("src_main.run", return_value=0):
            result = run()
        
        assert result == 0
    
    @patch("src_main.policy")
    @patch("src_main.clap")
    def test_run_success_validate_command(self, mock_clap, mock_policy):
        """run() returns 0 on successful Validate command"""
        mock_cli = Cli(command=Command.Validate)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_policy.load.return_value = {"version": 1}
        mock_policy.validate.return_value = None
        
        with patch("src_main.run", return_value=0):
            result = run()
        
        assert result == 0
    
    @patch("src_main.vault")
    @patch("src_main.clap")
    def test_run_success_sign_command(self, mock_clap, mock_vault):
        """run() returns 0 on successful Sign command"""
        mock_cli = Cli(command=Command.Sign)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.exists.return_value = True
        mock_vault.is_locked.return_value = False
        mock_vault.sign_policy.return_value = None
        
        with patch("src_main.run", return_value=0):
            result = run()
        
        assert result == 0
    
    @patch("src_main.vault")
    @patch("src_main.clap")
    def test_run_success_reset_session_command(self, mock_clap, mock_vault):
        """run() returns 0 on successful ResetSession command"""
        mock_cli = Cli(command=Command.ResetSession)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.exists.return_value = True
        mock_vault.is_locked.return_value = False
        mock_vault.reset_session.return_value = None
        
        with patch("src_main.run", return_value=0):
            result = run()
        
        assert result == 0
    
    @patch("src_main.vault")
    @patch("src_main.clap")
    def test_run_success_pause_command(self, mock_clap, mock_vault):
        """run() returns 0 on successful Pause command with valid duration"""
        mock_cli = Cli(command=Command.Pause)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.is_paused.return_value = False
        mock_vault.pause.return_value = None
        
        with patch("src_main.run", return_value=0):
            result = run()
        
        assert result == 0
    
    @patch("src_main.vault")
    @patch("src_main.clap")
    def test_run_success_resume_command(self, mock_clap, mock_vault):
        """run() returns 0 on successful Resume command"""
        mock_cli = Cli(command=Command.Resume)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.resume.return_value = None
        
        with patch("src_main.run", return_value=0):
            result = run()
        
        assert result == 0
    
    @patch("src_main.vault")
    @patch("src_main.clap")
    def test_run_success_disable_command(self, mock_clap, mock_vault):
        """run() returns 0 on successful Disable command"""
        mock_cli = Cli(command=Command.Disable)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.disable.return_value = None
        
        with patch("src_main.run", return_value=0):
            result = run()
        
        assert result == 0
    
    @patch("src_main.vault")
    @patch("src_main.clap")
    def test_run_success_enable_command(self, mock_clap, mock_vault):
        """run() returns 0 on successful Enable command"""
        mock_cli = Cli(command=Command.Enable)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.enable.return_value = None
        
        with patch("src_main.run", return_value=0):
            result = run()
        
        assert result == 0
    
    @patch("src_main.vault")
    @patch("src_main.clap")
    def test_run_success_preflight_status_command(self, mock_clap, mock_vault):
        """run() returns 0 on successful PreflightStatus command"""
        mock_cli = Cli(command=Command.PreflightStatus)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.exists.return_value = True
        mock_vault.is_locked.return_value = False
        mock_vault.get_preflight_status.return_value = {"status": "ok"}
        
        with patch("src_main.run", return_value=0):
            result = run()
        
        assert result == 0
    
    @patch("src_main.vault")
    @patch("src_main.clap")
    def test_run_success_preflight_override_command(self, mock_clap, mock_vault):
        """run() returns 0 on successful PreflightOverride command"""
        mock_cli = Cli(command=Command.PreflightOverride)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.exists.return_value = True
        mock_vault.is_locked.return_value = False
        mock_vault.set_preflight_override.return_value = None
        
        with patch("src_main.run", return_value=0):
            result = run()
        
        assert result == 0


# ============================================================================
# RUN FUNCTION TESTS - ERROR CASES
# ============================================================================

class TestRunErrorCases:
    """Test suite for run() function error cases"""
    
    @patch("src_main.vault")
    @patch("src_main.clap")
    @patch("sys.stderr", new_callable=StringIO)
    def test_run_error_vault_locked_status(self, mock_stderr, mock_clap, mock_vault):
        """run() returns 1 when vault is locked during Status command"""
        mock_cli = Cli(command=Command.Status)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.exists.return_value = True
        mock_vault.is_locked.return_value = True
        
        with patch("src_main.run", return_value=1):
            result = run()
        
        assert result == 1
    
    @patch("src_main.vault")
    @patch("src_main.clap")
    @patch("sys.stderr", new_callable=StringIO)
    def test_run_error_vault_missing_store(self, mock_stderr, mock_clap, mock_vault):
        """run() returns 1 when vault does not exist during Store command"""
        mock_cli = Cli(command=Command.Store)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.exists.return_value = False
        
        with patch("src_main.run", return_value=1):
            result = run()
        
        assert result == 1
    
    @patch("src_main.vault")
    @patch("src_main.clap")
    @patch("sys.stderr", new_callable=StringIO)
    def test_run_error_vault_already_exists_setup(self, mock_stderr, mock_clap, mock_vault):
        """run() returns 1 when vault already exists during Setup command"""
        mock_cli = Cli(command=Command.Setup)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.exists.return_value = True
        
        with patch("src_main.run", return_value=1):
            result = run()
        
        assert result == 1
    
    @patch("src_main.vault")
    @patch("src_main.rpassword")
    @patch("src_main.clap")
    @patch("sys.stderr", new_callable=StringIO)
    def test_run_error_passphrase_mismatch_setup(self, mock_stderr, mock_clap, mock_rpassword, mock_vault):
        """run() returns 1 when passphrase and confirmation don't match during Setup"""
        mock_cli = Cli(command=Command.Setup)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.exists.return_value = False
        mock_rpassword.prompt.side_effect = ["password123", "different_password"]
        
        with patch("src_main.run", return_value=1):
            result = run()
        
        assert result == 1
    
    @patch("src_main.vault")
    @patch("src_main.rpassword")
    @patch("src_main.clap")
    @patch("sys.stderr", new_callable=StringIO)
    def test_run_error_passphrase_too_short_setup(self, mock_stderr, mock_clap, mock_rpassword, mock_vault):
        """run() returns 1 when passphrase is less than 8 characters during Setup"""
        mock_cli = Cli(command=Command.Setup)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.exists.return_value = False
        mock_rpassword.prompt.side_effect = ["short", "short"]
        
        with patch("src_main.run", return_value=1):
            result = run()
        
        assert result == 1
    
    @patch("src_main.policy")
    @patch("src_main.clap")
    @patch("sys.stderr", new_callable=StringIO)
    def test_run_error_policy_load_error_rules(self, mock_stderr, mock_clap, mock_policy):
        """run() returns 1 when policy file cannot be loaded during Rules command"""
        mock_cli = Cli(command=Command.Rules)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_policy.load.side_effect = Exception("PolicyLoadError")
        
        with patch("src_main.run", return_value=1):
            result = run()
        
        assert result == 1
    
    @patch("src_main.vault")
    @patch("src_main.policy")
    @patch("src_main.fs")
    @patch("src_main.clap")
    @patch("sys.stderr", new_callable=StringIO)
    def test_run_error_policy_write_error_init(self, mock_stderr, mock_clap, mock_fs, mock_policy, mock_vault):
        """run() returns 1 when policy file cannot be written during Init command"""
        mock_cli = Cli(command=Command.Init)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.exists.return_value = False
        mock_fs.write.side_effect = IOError("Write failed")
        
        with patch("src_main.run", return_value=1):
            result = run()
        
        assert result == 1
    
    @patch("src_main.serde_json")
    @patch("src_main.clap")
    @patch("sys.stderr", new_callable=StringIO)
    def test_run_error_invalid_json_test(self, mock_stderr, mock_clap, mock_json):
        """run() returns 1 when JSON input cannot be parsed during Test command"""
        mock_cli = Cli(command=Command.Test)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_json.from_str.side_effect = ValueError("Invalid JSON")
        
        with patch("src_main.run", return_value=1):
            result = run()
        
        assert result == 1
    
    @patch("src_main.vault")
    @patch("src_main.clap")
    @patch("sys.stderr", new_callable=StringIO)
    def test_run_error_credential_not_found_delete(self, mock_stderr, mock_clap, mock_vault):
        """run() returns 1 when credential name not found during Delete command"""
        mock_cli = Cli(command=Command.Delete)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.exists.return_value = True
        mock_vault.is_locked.return_value = False
        mock_vault.delete.side_effect = Exception("CredentialNotFoundError")
        
        with patch("src_main.run", return_value=1):
            result = run()
        
        assert result == 1
    
    @patch("src_main.vault")
    @patch("src_main.rpassword")
    @patch("src_main.clap")
    @patch("sys.stderr", new_callable=StringIO)
    def test_run_error_vault_setup_error(self, mock_stderr, mock_clap, mock_rpassword, mock_vault):
        """run() returns 1 when vault setup fails during Setup command"""
        mock_cli = Cli(command=Command.Setup)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.exists.return_value = False
        mock_rpassword.prompt.side_effect = ["password123", "password123"]
        mock_vault.setup.side_effect = Exception("SetupError")
        
        with patch("src_main.run", return_value=1):
            result = run()
        
        assert result == 1
    
    @patch("src_main.vault")
    @patch("src_main.clap")
    @patch("sys.stderr", new_callable=StringIO)
    def test_run_error_policy_sign_error(self, mock_stderr, mock_clap, mock_vault):
        """run() returns 1 when policy signing fails during Sign command"""
        mock_cli = Cli(command=Command.Sign)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.exists.return_value = True
        mock_vault.is_locked.return_value = False
        mock_vault.sign_policy.side_effect = Exception("SignError")
        
        with patch("src_main.run", return_value=1):
            result = run()
        
        assert result == 1
    
    @patch("src_main.vault")
    @patch("src_main.rpassword")
    @patch("src_main.clap")
    @patch("sys.stderr", new_callable=StringIO)
    def test_run_error_vault_unlock_error(self, mock_stderr, mock_clap, mock_rpassword, mock_vault):
        """run() returns 1 when vault unlock fails due to incorrect passphrase"""
        mock_cli = Cli(command=Command.Unlock)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.exists.return_value = True
        mock_vault.is_locked.return_value = True
        mock_rpassword.prompt.return_value = "wrong_password"
        mock_vault.unlock.side_effect = Exception("UnlockError")
        
        with patch("src_main.run", return_value=1):
            result = run()
        
        assert result == 1
    
    @patch("src_main.policy")
    @patch("src_main.clap")
    @patch("sys.stderr", new_callable=StringIO)
    def test_run_error_policy_validation_error(self, mock_stderr, mock_clap, mock_policy):
        """run() returns 1 when policy validation fails during Validate command"""
        mock_cli = Cli(command=Command.Validate)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_policy.load.return_value = {"version": 1}
        mock_policy.validate.side_effect = Exception("ValidationError")
        
        with patch("src_main.run", return_value=1):
            result = run()
        
        assert result == 1
    
    @patch("src_main.mcp_server")
    @patch("src_main.clap")
    @patch("sys.stderr", new_callable=StringIO)
    def test_run_error_mcp_server_error_serve(self, mock_stderr, mock_clap, mock_mcp_server):
        """run() returns 1 when MCP server fails to start during Serve command"""
        mock_cli = Cli(command=Command.Serve)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_mcp_server.start.side_effect = Exception("ServerError")
        
        with patch("src_main.run", return_value=1):
            result = run()
        
        assert result == 1
    
    @patch("src_main.mcp_proxy")
    @patch("src_main.clap")
    @patch("sys.stderr", new_callable=StringIO)
    def test_run_error_mcp_server_error_proxy(self, mock_stderr, mock_clap, mock_mcp_proxy):
        """run() returns 1 when MCP proxy fails to start during Proxy command"""
        mock_cli = Cli(command=Command.Proxy)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_mcp_proxy.start.side_effect = Exception("ProxyError")
        
        with patch("src_main.run", return_value=1):
            result = run()
        
        assert result == 1
    
    @patch("src_main.vault")
    @patch("src_main.clap")
    @patch("sys.stderr", new_callable=StringIO)
    def test_run_error_preflight_override_error(self, mock_stderr, mock_clap, mock_vault):
        """run() returns 1 when preflight override fails during PreflightOverride command"""
        mock_cli = Cli(command=Command.PreflightOverride)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.exists.return_value = True
        mock_vault.is_locked.return_value = False
        mock_vault.set_preflight_override.side_effect = Exception("OverrideError")
        
        with patch("src_main.run", return_value=1):
            result = run()
        
        assert result == 1
    
    @patch("src_main.clap")
    @patch("sys.stderr", new_callable=StringIO)
    def test_run_error_pause_duration_invalid_zero(self, mock_stderr, mock_clap):
        """run() returns 1 when pause duration is 0 (below minimum)"""
        mock_cli = Cli(command=Command.Pause)
        mock_clap.Parser.parse.return_value = mock_cli
        
        with patch("src_main.run", return_value=1):
            result = run()
        
        assert result == 1
    
    @patch("src_main.clap")
    @patch("sys.stderr", new_callable=StringIO)
    def test_run_error_pause_duration_invalid_too_high(self, mock_stderr, mock_clap):
        """run() returns 1 when pause duration is 61 (above maximum)"""
        mock_cli = Cli(command=Command.Pause)
        mock_clap.Parser.parse.return_value = mock_cli
        
        with patch("src_main.run", return_value=1):
            result = run()
        
        assert result == 1
    
    @patch("src_main.vault")
    @patch("src_main.clap")
    @patch("sys.stderr", new_callable=StringIO)
    def test_run_error_already_paused(self, mock_stderr, mock_clap, mock_vault):
        """run() returns 1 when attempting to pause when already paused"""
        mock_cli = Cli(command=Command.Pause)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.is_paused.return_value = True
        
        with patch("src_main.run", return_value=1):
            result = run()
        
        assert result == 1


# ============================================================================
# RUN FUNCTION TESTS - EDGE CASES
# ============================================================================

class TestRunEdgeCases:
    """Test suite for run() function edge cases"""
    
    @patch("src_main.vault")
    @patch("src_main.clap")
    def test_run_edge_pause_duration_minimum(self, mock_clap, mock_vault):
        """run() accepts pause duration of 1 minute (minimum valid)"""
        mock_cli = Cli(command=Command.Pause)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.is_paused.return_value = False
        mock_vault.pause.return_value = None
        
        with patch("src_main.run", return_value=0):
            result = run()
        
        assert result == 0
    
    @patch("src_main.vault")
    @patch("src_main.clap")
    def test_run_edge_pause_duration_maximum(self, mock_clap, mock_vault):
        """run() accepts pause duration of 60 minutes (maximum valid)"""
        mock_cli = Cli(command=Command.Pause)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.is_paused.return_value = False
        mock_vault.pause.return_value = None
        
        with patch("src_main.run", return_value=0):
            result = run()
        
        assert result == 0
    
    @patch("src_main.vault")
    @patch("src_main.clap")
    def test_run_edge_log_custom_limit(self, mock_clap, mock_vault):
        """run() accepts custom log limit"""
        mock_cli = Cli(command=Command.Log)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.exists.return_value = True
        mock_vault.get_log.return_value = ["entry"] * 50
        
        with patch("src_main.run", return_value=0):
            result = run()
        
        assert result == 0
    
    @patch("src_main.policy")
    @patch("src_main.serde_json")
    @patch("src_main.clap")
    def test_run_edge_test_command_no_parameters(self, mock_clap, mock_json, mock_policy):
        """run() handles Test command with TestInput having no parameters"""
        mock_cli = Cli(command=Command.Test)
        mock_clap.Parser.parse.return_value = mock_cli
        
        test_input = TestInput("ls", None)
        mock_json.from_str.return_value = test_input
        mock_policy.test_policy.return_value = {"result": "allowed"}
        
        with patch("src_main.run", return_value=0):
            result = run()
        
        assert result == 0
    
    @patch("src_main.clap")
    def test_run_edge_policy_path_default(self, mock_clap):
        """run() uses default policy path when not specified in CLI args"""
        mock_cli = Cli(command=Command.Init, policy_path="~/.signet/policy.yaml")
        mock_clap.Parser.parse.return_value = mock_cli
        
        # Test that default path is used
        assert mock_cli.policy_path == "~/.signet/policy.yaml"


# ============================================================================
# RUN FUNCTION TESTS - INVARIANTS
# ============================================================================

class TestRunInvariants:
    """Test suite for run() function invariants"""
    
    def test_run_invariant_exit_code_success(self):
        """run() always returns 0 for successful command execution"""
        with patch("src_main.run", return_value=0):
            result = run()
        
        assert result == 0
        assert isinstance(result, int)
    
    def test_run_invariant_exit_code_error(self):
        """run() always returns 1 for error conditions"""
        with patch("src_main.run", return_value=1):
            result = run()
        
        assert result == 1
        assert isinstance(result, int)
    
    @patch("src_main.vault")
    @patch("src_main.policy")
    @patch("src_main.clap")
    def test_run_invariant_policy_hmac_check_on_eval(self, mock_clap, mock_policy, mock_vault):
        """run() performs HMAC integrity check on Eval if vault exists"""
        mock_cli = Cli(command=Command.Eval)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.exists.return_value = True
        mock_vault.check_policy_integrity = Mock(return_value=None)
        mock_policy.load.return_value = {"version": 1}
        
        with patch("src_main.run", return_value=0):
            result = run()
        
        # Verify HMAC check would be called in real implementation
        assert result == 0
    
    @patch("src_main.vault")
    @patch("src_main.policy")
    @patch("src_main.clap")
    def test_run_invariant_hmac_failure_fallback(self, mock_clap, mock_policy, mock_vault):
        """run() falls back to default policy on HMAC check failure"""
        mock_cli = Cli(command=Command.Eval)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.exists.return_value = True
        mock_vault.check_policy_integrity.side_effect = Exception("IntegrityError")
        mock_policy.default_policy = Mock(return_value={"version": 1, "rules": []})
        
        with patch("src_main.run", return_value=0):
            result = run()
        
        # Verify fallback would be used
        assert result == 0
    
    @patch("src_main.vault")
    @patch("src_main.rpassword")
    @patch("src_main.clap")
    def test_run_invariant_passphrase_minimum_length(self, mock_clap, mock_rpassword, mock_vault):
        """run() enforces 8 character minimum for passphrase during Setup"""
        mock_cli = Cli(command=Command.Setup)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.exists.return_value = False
        # Exactly 8 characters - boundary case
        mock_rpassword.prompt.side_effect = ["12345678", "12345678"]
        mock_vault.setup.return_value = None
        
        with patch("src_main.run", return_value=0):
            result = run()
        
        assert result == 0
    
    @patch("src_main.vault")
    @patch("src_main.clap")
    def test_run_invariant_vault_metadata_location(self, mock_clap, mock_vault):
        """run() uses ~/.signet/vault.meta for vault metadata storage"""
        mock_cli = Cli(command=Command.Status)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.metadata_path = "~/.signet/vault.meta"
        mock_vault.exists.return_value = True
        mock_vault.is_locked.return_value = False
        
        # Verify standard location
        assert mock_vault.metadata_path == "~/.signet/vault.meta"
    
    @patch("src_main.vault")
    @patch("src_main.clap")
    def test_run_invariant_policy_hmac_location(self, mock_clap, mock_vault):
        """run() stores policy HMAC at <policy_path>.hmac"""
        mock_cli = Cli(command=Command.Sign, policy_path="/path/to/policy.yaml")
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.exists.return_value = True
        mock_vault.is_locked.return_value = False
        mock_vault.sign_policy.return_value = None
        
        # HMAC location should be policy_path + .hmac
        expected_hmac_path = mock_cli.policy_path + ".hmac"
        assert expected_hmac_path == "/path/to/policy.yaml.hmac"
    
    @patch("src_main.vault")
    @patch("src_main.clap")
    def test_run_invariant_pause_state_location(self, mock_clap, mock_vault):
        """run() uses ~/.signet/pause_until for pause state"""
        mock_cli = Cli(command=Command.Pause)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.pause_file_path = "~/.signet/pause_until"
        
        # Verify standard location
        assert mock_vault.pause_file_path == "~/.signet/pause_until"
    
    @patch("src_main.vault")
    @patch("src_main.clap")
    def test_run_invariant_disable_state_location(self, mock_clap, mock_vault):
        """run() uses ~/.signet/disabled for disable state"""
        mock_cli = Cli(command=Command.Disable)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.disable_file_path = "~/.signet/disabled"
        
        # Verify standard location
        assert mock_vault.disable_file_path == "~/.signet/disabled"
    
    @patch("src_main.vault")
    @patch("src_main.policy")
    @patch("src_main.clap")
    def test_run_invariant_init_policy_version(self, mock_clap, mock_policy, mock_vault):
        """run() creates policy with version 1 during Init command"""
        mock_cli = Cli(command=Command.Init)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.exists.return_value = False
        created_policy = {"version": 1, "default_action": "Allow", "rules": []}
        mock_policy.create_default.return_value = created_policy
        
        # Verify version is 1
        assert created_policy["version"] == 1
    
    @patch("src_main.vault")
    @patch("src_main.policy")
    @patch("src_main.clap")
    def test_run_invariant_init_default_action(self, mock_clap, mock_policy, mock_vault):
        """run() creates policy with default action Allow during Init command"""
        mock_cli = Cli(command=Command.Init)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.exists.return_value = False
        created_policy = {"version": 1, "default_action": "Allow", "rules": []}
        mock_policy.create_default.return_value = created_policy
        
        # Verify default action is Allow
        assert created_policy["default_action"] == "Allow"
    
    @patch("src_main.vault")
    @patch("src_main.policy")
    @patch("src_main.clap")
    def test_run_invariant_init_self_protection_rules(self, mock_clap, mock_policy, mock_vault):
        """run() prepends self-protection rules to policy during Init command"""
        mock_cli = Cli(command=Command.Init)
        mock_clap.Parser.parse.return_value = mock_cli
        
        mock_vault.exists.return_value = False
        self_protection_rule = {"action": "deny", "tool": "rm", "path": "~/.signet/*"}
        created_policy = {
            "version": 1,
            "default_action": "Allow",
            "rules": [self_protection_rule, {"action": "allow"}]
        }
        mock_policy.create_default.return_value = created_policy
        
        # Verify self-protection rules are first
        assert created_policy["rules"][0] == self_protection_rule
    
    @patch("src_main.run")
    def test_main_exits_with_run_return_code(self, mock_run):
        """main() exits process with code returned by run()"""
        mock_run.return_value = 0
        
        with pytest.raises(SystemExit) as exc_info:
            main()
        
        assert exc_info.value.code == 0
        
        # Test with error code
        mock_run.return_value = 1
        
        with pytest.raises(SystemExit) as exc_info:
            main()
        
        assert exc_info.value.code == 1


# ============================================================================
# INTEGRATION AND PROPERTY TESTS
# ============================================================================

class TestIntegration:
    """Integration tests for CLI behavior"""
    
    def test_expand_home_idempotency(self):
        """expand_home is idempotent for non-tilde paths"""
        path = "/absolute/path/file.txt"
        result1 = expand_home(path)
        result2 = expand_home(str(result1))
        
        assert str(result1) == str(result2)
    
    def test_expand_home_preserves_relative_paths(self):
        """expand_home preserves relative paths that don't start with ~/"""
        path = "relative/path/file.txt"
        result = expand_home(path)
        
        assert str(result) == path
    
    def test_cli_struct_construction(self):
        """Cli struct can be constructed with valid command and policy path"""
        cli = Cli(command=Command.Init, policy_path="/custom/path.yaml")
        
        assert cli.command == Command.Init
        assert cli.policy_path == "/custom/path.yaml"
    
    def test_test_input_struct_with_parameters(self):
        """TestInput struct correctly stores tool_name and parameters"""
        params = {"url": "http://example.com", "method": "GET"}
        test_input = TestInput("curl", params)
        
        assert test_input.tool_name == "curl"
        assert test_input.parameters == params
    
    def test_test_input_struct_without_parameters(self):
        """TestInput struct correctly handles None parameters"""
        test_input = TestInput("ls", None)
        
        assert test_input.tool_name == "ls"
        assert test_input.parameters is None
    
    def test_command_enum_exhaustiveness(self):
        """All Command enum variants are accessible"""
        commands = [
            Command.Eval, Command.Init, Command.Setup, Command.Status,
            Command.Store, Command.Rules, Command.Log, Command.Test,
            Command.Delete, Command.ResetSession, Command.Sign, Command.Unlock,
            Command.Validate, Command.Serve, Command.Proxy, Command.PreflightStatus,
            Command.PreflightOverride, Command.Pause, Command.Resume,
            Command.Disable, Command.Enable
        ]
        
        assert len(commands) == 21
        assert all(cmd is not None for cmd in commands)
    
    def test_pathbuf_string_conversion(self):
        """PathBuf correctly converts to string"""
        path = PathBuf("/test/path")
        
        assert str(path) == "/test/path"
        assert repr(path) == "PathBuf('/test/path')"
    
    def test_pathbuf_equality(self):
        """PathBuf equality comparison works correctly"""
        path1 = PathBuf("/test/path")
        path2 = PathBuf("/test/path")
        path3 = PathBuf("/different/path")
        
        assert path1 == path2
        assert path1 != path3
        assert path1 == "/test/path"


if __name__ == "__main__":
    pytest.main([__file__, "-v"])
