"""
Extended tests for the CLI commands.
"""

import os
import sys
from pathlib import Path
from unittest.mock import MagicMock, patch

import pytest
import typer
from typer.testing import CliRunner

from airulefy.__main__ import app


runner = CliRunner()


def setup_test_project(tmp_path: Path):
    """Set up a test project structure."""
    # Create .ai directory
    ai_dir = tmp_path / ".ai"
    ai_dir.mkdir()
    
    # Create Markdown files
    file1 = ai_dir / "main.md"
    file1.write_text("# Main Rules\n\nThese are the main rules.")
    
    # Create config file
    config_file = tmp_path / ".ai-rules.yml"
    config_file.write_text("""
default_mode: symlink
tools:
  cursor: {}
  cline: {}
  copilot: {}
  devin: {}
""")
    
    return [file1]


def test_validate_command_success(tmp_path, monkeypatch):
    """Test validate command with a valid configuration."""
    # Set up test project
    setup_test_project(tmp_path)
    
    # Change working directory to tmp_path
    monkeypatch.chdir(tmp_path)
    
    # Run validate command
    result = runner.invoke(app, ["validate"])
    
    # Check result
    assert result.exit_code == 0
    assert "All checks passed" in result.stdout


def test_validate_command_missing_dir(tmp_path, monkeypatch):
    """Test validate command with missing input directory."""
    # Set up config file only
    config_file = tmp_path / ".ai-rules.yml"
    config_file.write_text("""
default_mode: symlink
input_path: "non_existent_directory"
tools:
  cursor: {}
  cline: {}
  copilot: {}
  devin: {}
""")
    
    # Change working directory to tmp_path
    monkeypatch.chdir(tmp_path)
    
    # Run validate command
    result = runner.invoke(app, ["validate"])
    
    # Check result
    assert result.exit_code == 1
    assert "Errors:" in result.stdout
    assert "Input directory not found" in result.stdout


def test_validate_command_no_files(tmp_path, monkeypatch):
    """Test validate command with no markdown files."""
    # Create empty input directory
    input_dir = tmp_path / ".ai"
    input_dir.mkdir()
    
    # Create config file
    config_file = tmp_path / ".ai-rules.yml"
    config_file.write_text("""
default_mode: symlink
tools:
  cursor: {}
  cline: {}
  copilot: {}
  devin: {}
""")
    
    # Change working directory to tmp_path
    monkeypatch.chdir(tmp_path)
    
    # Run validate command
    result = runner.invoke(app, ["validate"])
    
    # Check result
    assert result.exit_code == 0
    assert "Warnings:" in result.stdout
    assert "No Markdown files found" in result.stdout


def test_validate_command_invalid_output(tmp_path, monkeypatch):
    """Test validate command with an invalid output path."""
    # Set up test project
    setup_test_project(tmp_path)
    
    # Create a directory that conflicts with an output path
    conflict_dir = tmp_path / ".cursor"
    conflict_dir.mkdir()
    (conflict_dir / "rules").mkdir()
    # Create a directory where a file should be
    (conflict_dir / "rules" / "core.mdc").mkdir()
    
    # Change working directory to tmp_path
    monkeypatch.chdir(tmp_path)
    
    # Run validate command
    result = runner.invoke(app, ["validate"])
    
    # Check result
    assert result.exit_code == 1
    assert "Errors:" in result.stdout
    assert "exists but is not a file" in result.stdout


def test_list_tools_command(tmp_path, monkeypatch):
    """Test list-tools command."""
    # Set up test project
    setup_test_project(tmp_path)
    
    # Change working directory to tmp_path
    monkeypatch.chdir(tmp_path)
    
    # Run list-tools command
    result = runner.invoke(app, ["list-tools"])
    
    # Check result
    assert result.exit_code == 0
    assert "Supported AI Tools" in result.stdout
    assert "cursor" in result.stdout
    assert "cline" in result.stdout
    assert "copilot" in result.stdout
    assert "devin" in result.stdout


@patch('airulefy.__main__.watch_directory')  # パスを修正
def test_watch_command(mock_watch, tmp_path, monkeypatch):
    """Test watch command."""
    # Set up test project
    setup_test_project(tmp_path)
    
    # Change working directory to tmp_path
    monkeypatch.chdir(tmp_path)
    
    # Run watch command
    result = runner.invoke(app, ["watch"])
    
    # Check result
    assert "Watching" in result.stdout
    assert "for changes" in result.stdout
    
    # Check that watch_directory was called
    mock_watch.assert_called_once()


def test_watch_command_missing_dir(tmp_path, monkeypatch):
    """Test watch command with missing input directory."""
    # Create config file with non-existent directory
    config_file = tmp_path / ".ai-rules.yml"
    config_file.write_text("""
default_mode: symlink
input_path: "non_existent_directory"
tools:
  cursor: {}
  cline: {}
  copilot: {}
  devin: {}
""")
    
    # Change working directory to tmp_path
    monkeypatch.chdir(tmp_path)
    
    # Run watch command
    result = runner.invoke(app, ["watch"])
    
    # Check result
    assert "Directory not found" in result.stdout
    # ディレクトリが存在しないことを確認するだけで十分
    # 実際のパスはテスト環境によって異なる場合がある


def test_generate_verbose_mode(tmp_path, monkeypatch):
    """Test generate command with verbose output."""
    # Set up test project
    md_files = setup_test_project(tmp_path)
    
    # Change working directory to tmp_path
    monkeypatch.chdir(tmp_path)
    
    # Run generate command with verbose flag
    result = runner.invoke(app, ["generate", "--verbose"])
    
    # Check result
    assert result.exit_code == 0
    assert "Found 1 Markdown files in" in result.stdout
    assert "Generating rules for" in result.stdout
    assert "Successfully generated" in result.stdout


def test_generate_with_skipped_unknown_tool(tmp_path, monkeypatch):
    """Test generate command with an unknown tool in config."""
    # Set up test project
    md_files = setup_test_project(tmp_path)
    
    # Add unknown tool to config
    config_file = tmp_path / ".ai-rules.yml"
    config_file.write_text("""
default_mode: symlink
tools:
  cursor: {}
  cline: {}
  copilot: {}
  devin: {}
  unknown_tool: {}
""")
    
    # Change working directory to tmp_path
    monkeypatch.chdir(tmp_path)
    
    # Run generate command with verbose flag
    result = runner.invoke(app, ["generate", "--verbose"])
    
    # Check result
    assert result.exit_code == 0
    assert "Skipping unknown tool: unknown_tool" in result.stdout


def test_generate_no_files_found(tmp_path, monkeypatch):
    """Test generate command when no Markdown files are found."""
    # Create empty .ai directory
    ai_dir = tmp_path / ".ai"
    ai_dir.mkdir()
    
    # Create config file
    config_file = tmp_path / ".ai-rules.yml"
    config_file.write_text("""
default_mode: symlink
tools:
  cursor: {}
  cline: {}
  copilot: {}
  devin: {}
""")
    
    # Change working directory to tmp_path
    monkeypatch.chdir(tmp_path)
    
    # Run generate command
    result = runner.invoke(app, ["generate"])
    
    # Check result
    assert result.exit_code == 0
    assert "No Markdown files found in" in result.stdout
