"""
Comprehensive Test for Tool Human-in-the-Loop Attributes
Tests: requires_confirmation, requires_user_input, user_input_fields

These tests require manual user interaction
Run manually with: python3 tests/smoke_tests/test_tool_hitl_attributes.py
"""
import pytest
from upsonic.tools import tool
from upsonic import Agent, Task


class TestRequiresConfirmation:
    """Test requires_confirmation attribute"""
    
    def test_tool_requires_confirmation(self):
        """Test tool that requires user confirmation before execution"""
        
        @tool(requires_confirmation=True)
        def delete_file(file_path: str) -> str:
            """
            Delete a file from the system.
            
            Args:
                file_path: Path to the file to delete
            
            Returns:
                Confirmation message
            """
            # In real scenario, would actually delete the file
            return f"File {file_path} deleted successfully"
        
        # Create task that uses the tool
        task = Task(
            description="Delete the file /tmp/test.txt using the delete_file tool",
            tools=[delete_file]
        )
        
        agent = Agent(model="openai/gpt-4o-mini")
        
        # This should pause for confirmation
        # User needs to manually confirm the action
        result = agent.do(task)
        
        # After manual confirmation, the task should complete
        assert "deleted" in result.lower() or task.is_paused
        
    def test_multiple_confirmations(self):
        """Test multiple tools requiring confirmation"""
        
        @tool(requires_confirmation=True)
        def dangerous_operation_1(data: str) -> str:
            """Dangerous operation 1"""
            return f"Executed operation 1 on {data}"
        
        @tool(requires_confirmation=True)
        def dangerous_operation_2(data: str) -> str:
            """Dangerous operation 2"""
            return f"Executed operation 2 on {data}"
        
        task = Task(
            description="Execute both dangerous operations on 'test_data'",
            tools=[dangerous_operation_1, dangerous_operation_2]
        )
        
        agent = Agent(model="openai/gpt-4o-mini")
        result = agent.do(task)
        
        # Should require multiple confirmations
        assert result or task.is_paused


class TestRequiresUserInput:
    """Test requires_user_input and user_input_fields attributes"""
    
    def test_tool_requires_user_input(self):
        """Test tool that requires user input for specific fields"""
        
        @tool(
            requires_user_input=True,
            user_input_fields=["username", "password"]
        )
        def secure_login(username: str, password: str) -> str:
            """
            Login with user-provided credentials.
            
            Args:
                username: Username for login
                password: Password for login
            
            Returns:
                Login status message
            """
            # In real scenario, would validate credentials
            return f"Login successful for user: {username}"
        
        task = Task(
            description="Login to the system using the secure_login tool",
            tools=[secure_login]
        )
        
        agent = Agent(model="openai/gpt-4o-mini")
        
        # This should pause and wait for user to provide username and password
        result = agent.do(task)
        
        # After user provides input, task should complete
        assert "Login successful" in result or task.is_paused
        
    def test_partial_user_input_fields(self):
        """Test tool with some fields requiring user input"""
        
        @tool(
            requires_user_input=True,
            user_input_fields=["api_key"]
        )
        def api_call(endpoint: str, api_key: str, data: str = "") -> str:
            """
            Make an API call with user-provided API key.
            
            Args:
                endpoint: API endpoint
                api_key: API key (user must provide)
                data: Optional data
            
            Returns:
                API response
            """
            return f"Called {endpoint} with key {api_key[:5]}..."
        
        task = Task(
            description="Call the /users endpoint with some data",
            tools=[api_call]
        )
        
        agent = Agent(model="openai/gpt-4o-mini")
        result = agent.do(task)
        
        # Should pause for api_key input
        assert result or task.is_paused


class TestCombinedHITLAttributes:
    """Test combinations of HITL attributes"""
    
    def test_confirmation_and_user_input(self):
        """Test tool requiring both confirmation and user input"""
        
        @tool(
            requires_confirmation=True,
            requires_user_input=True,
            user_input_fields=["password"]
        )
        def delete_with_password(file_path: str, password: str) -> str:
            """
            Delete a file after password confirmation.
            
            Args:
                file_path: File to delete
                password: Admin password
            
            Returns:
                Result message
            """
            return f"Deleted {file_path} after password verification"
        
        task = Task(
            description="Delete /important/file.txt with password verification",
            tools=[delete_with_password]
        )
        
        agent = Agent(model="openai/gpt-4o-mini")
        result = agent.do(task)
        
        # Should pause for both confirmation and user input
        assert task.is_paused or "Deleted" in result


if __name__ == "__main__":
    print("=" * 80)
    print("WARNING: These tests require manual user interaction!")
    print("They will pause and wait for user input/confirmation.")
    print("Run them individually and provide input as needed.")
    print("=" * 80)
    pytest.main([__file__, "-v", "-s"])

