import subprocess
import sys
import tempfile
import os
from pathlib import Path


def test_cli_valid_program():
    """Test running a valid program through the CLI."""
    # Create a temporary file with a valid program
    with tempfile.NamedTemporaryFile(mode='w', suffix='.ink', delete=False, encoding='utf-8') as f:
        f.write('若A則B\n')
        f.write('曰A\n')
        f.write('問B乎\n')
        temp_file = f.name
    
    try:
        # Run the CLI
        result = subprocess.run(
            [sys.executable, '-m', 'ink.cli', temp_file],
            capture_output=True,
            text=True
        )
        
        # Should succeed with exit code 0
        assert result.returncode == 0
        # Should output ⊤ (B is derivable from A)
        assert '⊤' in result.stdout
    finally:
        os.unlink(temp_file)


def test_cli_file_not_found():
    """Test CLI error handling for missing file."""
    result = subprocess.run(
        [sys.executable, '-m', 'ink.cli', 'nonexistent_file.ink'],
        capture_output=True,
        text=True
    )
    
    # Should fail with exit code 1
    assert result.returncode == 1
    # Should output error message
    assert 'file not found' in result.stdout.lower() or 'file not found' in result.stderr.lower()


def test_cli_parse_error():
    """Test CLI error handling for parse errors."""
    # Create a temporary file with invalid syntax
    with tempfile.NamedTemporaryFile(mode='w', suffix='.ink', delete=False, encoding='utf-8') as f:
        f.write('若A\n')  # Missing 則 and conclusion
        temp_file = f.name
    
    try:
        result = subprocess.run(
            [sys.executable, '-m', 'ink.cli', temp_file],
            capture_output=True,
            text=True
        )
        
        # Should fail with exit code 1
        assert result.returncode == 1
        # Should output parse error message
        assert 'parse error' in result.stdout.lower() or 'error' in result.stdout.lower()
    finally:
        os.unlink(temp_file)


def test_cli_lexer_error():
    """Test CLI error handling for lexer errors."""
    # Create a temporary file with invalid characters
    with tempfile.NamedTemporaryFile(mode='w', suffix='.ink', delete=False, encoding='utf-8') as f:
        f.write('曰A\n')
        f.write('@#$%\n')  # Invalid characters
        temp_file = f.name
    
    try:
        result = subprocess.run(
            [sys.executable, '-m', 'ink.cli', temp_file],
            capture_output=True,
            text=True
        )
        
        # Should fail with exit code 1
        assert result.returncode == 1
        # Should output lexer error message
        assert 'lexer error' in result.stdout.lower() or 'error' in result.stdout.lower()
    finally:
        os.unlink(temp_file)


def test_cli_missing_filename():
    """Test CLI error handling for missing filename argument."""
    result = subprocess.run(
        [sys.executable, '-m', 'ink.cli'],
        capture_output=True,
        text=True
    )
    
    # Should fail with exit code 1
    assert result.returncode == 1
    # Should output usage instructions
    assert 'usage' in result.stdout.lower() or 'usage' in result.stderr.lower()


def test_cli_undeclared_verb_error():
    """Test CLI error handling for undeclared verb in SVO clause."""
    # Create a temporary file with undeclared verb
    with tempfile.NamedTemporaryFile(mode='w', suffix='.ink', delete=False, encoding='utf-8') as f:
        f.write('甲愛乙\n')  # 愛 is not declared as a verb
        temp_file = f.name
    
    try:
        result = subprocess.run(
            [sys.executable, '-m', 'ink.cli', temp_file],
            capture_output=True,
            text=True
        )
        
        # Should fail with exit code 1
        assert result.returncode == 1
        # Should output parse error about undeclared verb
        assert 'error' in result.stdout.lower()
    finally:
        os.unlink(temp_file)


def test_cli_query_not_derivable():
    """Test CLI with query that is not derivable."""
    # Create a temporary file with a query that should fail
    with tempfile.NamedTemporaryFile(mode='w', suffix='.ink', delete=False, encoding='utf-8') as f:
        f.write('曰A\n')
        f.write('問B乎\n')  # B is not derivable
        temp_file = f.name
    
    try:
        result = subprocess.run(
            [sys.executable, '-m', 'ink.cli', temp_file],
            capture_output=True,
            text=True
        )
        
        # Should succeed with exit code 0
        assert result.returncode == 0
        # Should output ? (B is not derivable)
        assert '?' in result.stdout
    finally:
        os.unlink(temp_file)
