"""
Tests for Issue #38 Phase 1: Command Restructuring

This module tests the restructuring of metadata command to db-data
and ensures backward compatibility with proper deprecation warnings.

Issue #38: Access metadata, frontmatter, content separately in CLI
Phase 1: Rename metadata command to db-data for consistency
"""

import pytest
from click.testing import CliRunner
from unittest.mock import patch, MagicMock

from markitect.cli import cli


class TestIssue38CommandRestructuring:
    """Test suite for Issue #38 Phase 1: Command restructuring."""

    def setup_method(self):
        """Set up test fixtures."""
        self.runner = CliRunner()
        self.sample_metadata = {
            'id': 1,
            'filename': 'test.md',
            'created_at': '2025-09-30 12:00:00',
            'front_matter': '{"title": "Test Document", "author": "Test Author"}',
            'content': '# Test Document\n\nThis is test content.'
        }

    def test_db_data_command_exists(self):
        """
        Test that new db-data command exists and is accessible.

        Issue #38 Phase 1: Command restructuring
        """
        result = self.runner.invoke(cli, ['db-data', '--help'])

        assert result.exit_code == 0
        assert 'db-data' in result.output.lower()
        assert 'display file metadata' in result.output.lower() or 'metadata' in result.output.lower()

    def test_db_data_command_functionality(self):
        """
        Test that db-data command works with same functionality as old metadata command.

        Issue #38 Phase 1: Command restructuring
        """
        with patch('markitect.cli.DatabaseManager') as mock_db_mgr:
            mock_db_instance = MagicMock()
            mock_db_mgr.return_value = mock_db_instance
            mock_db_instance.get_markdown_file.return_value = self.sample_metadata

            result = self.runner.invoke(cli, ['db-data', 'test.md'])

            assert result.exit_code == 0
            assert 'test.md' in result.output
            assert 'Test Document' in result.output
            assert 'Test Author' in result.output

    def test_db_data_supports_all_output_formats(self):
        """
        Test that db-data command supports all output formats (table, json, yaml).

        Issue #38 Phase 1: Command restructuring
        """
        with patch('markitect.cli.DatabaseManager') as mock_db_mgr:
            mock_db_instance = MagicMock()
            mock_db_mgr.return_value = mock_db_instance
            mock_db_instance.get_markdown_file.return_value = self.sample_metadata

            # Test JSON format
            result = self.runner.invoke(cli, ['db-data', 'test.md', '--format', 'json'])
            assert result.exit_code == 0

            # Test YAML format
            result = self.runner.invoke(cli, ['db-data', 'test.md', '--format', 'yaml'])
            assert result.exit_code == 0

            # Test table format
            result = self.runner.invoke(cli, ['db-data', 'test.md', '--format', 'table'])
            assert result.exit_code == 0

    def test_metadata_command_still_exists_with_deprecation_warning(self):
        """
        Test that old metadata command still works but shows deprecation warning.

        Issue #38 Phase 1: Backward compatibility with deprecation
        """
        with patch('markitect.cli.DatabaseManager') as mock_db_mgr:
            mock_db_instance = MagicMock()
            mock_db_mgr.return_value = mock_db_instance
            mock_db_instance.get_markdown_file.return_value = self.sample_metadata

            result = self.runner.invoke(cli, ['metadata', 'test.md'])

            # Should still work (backward compatibility)
            assert result.exit_code == 0
            assert 'test.md' in result.output

            # Should show deprecation warning
            assert ('deprecated' in result.output.lower() or
                    'warning' in result.output.lower() or
                    'db-data' in result.output.lower())

    def test_metadata_command_redirect_suggestion(self):
        """
        Test that metadata command suggests using db-data instead.

        Issue #38 Phase 1: User guidance for migration
        """
        result = self.runner.invoke(cli, ['metadata', '--help'])

        assert result.exit_code == 0
        # Should suggest the new command
        assert 'db-data' in result.output.lower()

    def test_db_data_command_error_handling(self):
        """
        Test that db-data command handles errors gracefully.

        Issue #38 Phase 1: Error handling consistency
        """
        with patch('markitect.cli.DatabaseManager') as mock_db_mgr:
            mock_db_instance = MagicMock()
            mock_db_mgr.return_value = mock_db_instance
            mock_db_instance.get_markdown_file.side_effect = FileNotFoundError("File not found")

            result = self.runner.invoke(cli, ['db-data', 'nonexistent.md'])

            # Should handle error gracefully
            assert result.exit_code != 0 or 'not found' in result.output.lower()

    def test_help_consistency_between_commands(self):
        """
        Test that db-data and metadata commands have consistent help information.

        Issue #38 Phase 1: Documentation consistency
        """
        # Get help for both commands
        db_data_help = self.runner.invoke(cli, ['db-data', '--help'])
        metadata_help = self.runner.invoke(cli, ['metadata', '--help'])

        assert db_data_help.exit_code == 0
        assert metadata_help.exit_code == 0

        # Both should mention similar functionality
        assert '--format' in db_data_help.output
        assert '--format' in metadata_help.output

    def test_db_data_command_follows_db_prefix_pattern(self):
        """
        Test that db-data command follows the established db- prefix pattern.

        Issue #38 Phase 1: Consistency with Issue #39 db- reorganization
        """
        # Check that db-data command appears in help alongside other db- commands
        result = self.runner.invoke(cli, ['--help'])

        assert result.exit_code == 0
        help_output = result.output.lower()

        # Should see db-data alongside other db- commands
        assert 'db-data' in help_output
        # Should also see other established db- commands
        assert 'db-query' in help_output or 'db-schema' in help_output


class TestIssue38BackwardCompatibility:
    """Test suite for backward compatibility during command restructuring."""

    def setup_method(self):
        """Set up test fixtures."""
        self.runner = CliRunner()

    def test_existing_scripts_continue_working(self):
        """
        Test that existing scripts using metadata command continue to work.

        Issue #38 Phase 1: Backward compatibility guarantee
        """
        with patch('markitect.cli.DatabaseManager') as mock_db_mgr:
            mock_db_instance = MagicMock()
            mock_db_mgr.return_value = mock_db_instance
            mock_db_instance.get_markdown_file.return_value = {
                'filename': 'test.md',
                'front_matter': '{"title": "Test"}'
            }

            # Simulate existing script usage
            result = self.runner.invoke(cli, ['metadata', 'test.md', '--format', 'json'])

            # Must continue working for backward compatibility
            assert result.exit_code == 0
            assert 'test.md' in result.output

    def test_migration_path_documentation(self):
        """
        Test that clear migration path is provided from metadata to db-data.

        Issue #38 Phase 1: User migration guidance
        """
        result = self.runner.invoke(cli, ['metadata', '--help'])

        assert result.exit_code == 0
        help_text = result.output.lower()

        # Should provide clear migration guidance
        assert ('db-data' in help_text or
                'use db-data instead' in help_text or
                'deprecated' in help_text)


