"""
Example Integration: Adding Legacy Support to MarkiTect CLI Commands

This file demonstrates how to integrate the legacy compatibility system
into existing MarkiTect CLI commands, showing practical patterns for:

1. Adding legacy switches to existing commands
2. Creating compatibility adapters for breaking changes
3. Registering legacy interfaces and deprecation timelines
4. Setting up automated legacy management

This serves as both documentation and a working example.
"""

import click
import json
from datetime import datetime, timedelta
from pathlib import Path

# Import the legacy system components
from .legacy import (
    LegacyRegistry, LegacySwitch, LegacyAgent, DeprecationManager,
    GitStateTracker, CompatibilityLayer, LegacyStatus, legacy_option,
    with_legacy_support
)
from .legacy.compatibility import InterfaceAdapter, ParameterMapping


# Example 1: Adding legacy support to the existing 'query' command
# This shows how to modify an existing command to support legacy versions

@click.command()
@click.argument('sql', type=str)
@click.option('--format', '-f', type=click.Choice(['table', 'json', 'yaml', 'simple']),
              default='simple', help='Output format')
@legacy_option('v1.0', 'Use v1.0 legacy query behavior (deprecated)')
@legacy_option('v2.0', 'Use v2.0 legacy query behavior (deprecated)')
@with_legacy_support('query')
def query_with_legacy(sql, format, legacy_v1_0=False, legacy_v2_0=False):
    """
    Execute SQL query with legacy support.

    This demonstrates how an existing command can be enhanced with legacy support
    without breaking existing functionality.
    """
    # The @with_legacy_support decorator handles legacy routing automatically
    # If no legacy flags are set, this executes the modern implementation

    # Modern implementation
    return execute_modern_query(sql, format)


def execute_modern_query(sql: str, format: str):
    """Modern query implementation."""
    # This would be your current implementation
    return f"Modern query result for: {sql} in {format} format"


# Example 2: Setting up legacy compatibility adapters
# This shows how to handle breaking changes between versions

def setup_query_legacy_adapters():
    """Setup compatibility adapters for query command legacy versions."""

    compatibility = CompatibilityLayer()

    # Adapter for v1.0 - handles parameter name changes
    v1_adapter = InterfaceAdapter(
        legacy_version='v1.0',
        parameter_mappings=[
            ParameterMapping(
                legacy_name='sql_query',  # Old parameter name
                modern_name='sql',        # New parameter name
                required=True
            ),
            ParameterMapping(
                legacy_name='output_format',  # Old parameter name
                modern_name='format',         # New parameter name
                transformer=lambda x: {       # Handle format value changes
                    'pretty': 'table',
                    'raw': 'simple',
                    'structured': 'json'
                }.get(x, x),
                default_value='simple'
            ),
            ParameterMapping(
                legacy_name='verbose_output',  # Boolean flag converted to format
                modern_name='format',
                transformer=lambda x: 'table' if x else 'simple',
                required=False
            )
        ],
        return_transformer=legacy_v1_return_format,  # Transform output format
        compatibility_mode=CompatibilityLayer.CompatibilityMode.ADAPTIVE
    )

    # Adapter for v2.0 - handles different breaking changes
    v2_adapter = InterfaceAdapter(
        legacy_version='v2.0',
        parameter_mappings=[
            ParameterMapping(
                legacy_name='database_query',  # Another old name
                modern_name='sql',
                required=True
            ),
            ParameterMapping(
                legacy_name='response_format',
                modern_name='format',
                transformer=lambda x: x.lower(),  # Simple case conversion
                default_value='simple'
            )
        ],
        return_transformer=legacy_v2_return_format,
        compatibility_mode=CompatibilityLayer.CompatibilityMode.STRICT
    )

    compatibility.register_adapter('query', v1_adapter)
    compatibility.register_adapter('query', v2_adapter)

    return compatibility


def legacy_v1_return_format(result):
    """Transform modern query results to v1.0 expected format."""
    if isinstance(result, str) and 'Modern query result' in result:
        # v1.0 expected results wrapped in a specific structure
        return {
            'status': 'success',
            'query_result': result,
            'format_version': 'v1.0',
            'timestamp': datetime.now().isoformat()
        }
    return result


def legacy_v2_return_format(result):
    """Transform modern query results to v2.0 expected format."""
    if isinstance(result, str):
        # v2.0 expected a different wrapper structure
        return {
            'success': True,
            'data': result,
            'api_version': 'v2.0'
        }
    return result


# Example 3: Registering legacy interfaces with the registry
# This shows how to formally register legacy versions

def register_query_legacy_versions():
    """Register legacy versions of the query command."""

    registry = LegacyRegistry()
    git_tracker = GitStateTracker()

    # Register v1.0 as deprecated (90 days ago)
    deprecated_date = (datetime.now() - timedelta(days=90)).isoformat()

    registry.register_legacy_interface(
        command='query',
        version='v1.0',
        git_commit='a1b2c3d4',  # Actual commit where v1.0 was current
        status=LegacyStatus.DEPRECATED,
        deprecated_date=deprecated_date,
        removal_date=(datetime.now() + timedelta(days=60)).isoformat(),
        description='Legacy query interface with sql_query parameter',
        breaking_changes=[
            'Parameter sql_query renamed to sql',
            'Output format values changed (pretty->table, raw->simple)',
            'Return structure modified for consistency'
        ],
        migration_guide='''
Migration from query v1.0 to current:

1. Change parameter names:
   --sql_query → --sql (or use sql as positional argument)
   --output_format → --format

2. Update format values:
   --output_format=pretty → --format=table
   --output_format=raw → --format=simple
   --output_format=structured → --format=json

3. Update result parsing:
   - v1.0 returned: {"status": "success", "query_result": "...", ...}
   - Current returns: direct result string or structured data

Example:
  Old: markitect query --sql_query "SELECT * FROM files" --output_format=pretty
  New: markitect query "SELECT * FROM files" --format=table
        ''',
        implementation=legacy_v1_query_implementation
    )

    # Register v2.0 as legacy (requires flag)
    registry.register_legacy_interface(
        command='query',
        version='v2.0',
        git_commit='e5f6g7h8',  # Actual commit where v2.0 was current
        status=LegacyStatus.LEGACY,
        deprecated_date=(datetime.now() - timedelta(days=30)).isoformat(),
        removal_date=(datetime.now() + timedelta(days=90)).isoformat(),
        description='Legacy query interface with database_query parameter',
        breaking_changes=[
            'Parameter database_query renamed to sql',
            'Response format structure simplified'
        ],
        migration_guide='''
Migration from query v2.0 to current:

1. Change parameter names:
   --database_query → positional sql argument

2. Update result parsing:
   - v2.0 returned: {"success": true, "data": "...", "api_version": "v2.0"}
   - Current returns: direct result

Example:
  Old: markitect query --database_query "SELECT * FROM files"
  New: markitect query "SELECT * FROM files"
        ''',
        implementation=legacy_v2_query_implementation
    )

    # Bind versions to git commits for precise restoration
    git_tracker.bind_version_to_commit(
        command='query',
        version='v1.0',
        commit_hash='a1b2c3d4',
        description='Query v1.0 implementation with sql_query parameter',
        validation_files=['markitect/cli.py', 'markitect/database.py']
    )

    git_tracker.bind_version_to_commit(
        command='query',
        version='v2.0',
        commit_hash='e5f6g7h8',
        description='Query v2.0 implementation with database_query parameter',
        validation_files=['markitect/cli.py', 'markitect/database.py']
    )


def legacy_v1_query_implementation(*args, **kwargs):
    """Legacy v1.0 query implementation."""
    # Extract legacy parameters
    sql_query = kwargs.get('sql_query') or args[0] if args else None
    output_format = kwargs.get('output_format', 'simple')
    verbose_output = kwargs.get('verbose_output', False)

    if not sql_query:
        raise ValueError("sql_query parameter is required for v1.0")

    # Transform to modern parameters
    modern_format = {
        'pretty': 'table',
        'raw': 'simple',
        'structured': 'json'
    }.get(output_format, output_format)

    if verbose_output:
        modern_format = 'table'

    # Execute modern implementation
    result = execute_modern_query(sql_query, modern_format)

    # Return in v1.0 expected format
    return {
        'status': 'success',
        'query_result': result,
        'format_version': 'v1.0',
        'timestamp': datetime.now().isoformat()
    }


def legacy_v2_query_implementation(*args, **kwargs):
    """Legacy v2.0 query implementation."""
    database_query = kwargs.get('database_query') or args[0] if args else None
    response_format = kwargs.get('response_format', 'simple').lower()

    if not database_query:
        raise ValueError("database_query parameter is required for v2.0")

    # Execute modern implementation
    result = execute_modern_query(database_query, response_format)

    # Return in v2.0 expected format
    return {
        'success': True,
        'data': result,
        'api_version': 'v2.0'
    }


# Example 4: Setting up automated legacy management
# This shows how to configure the legacy agent for automation

def setup_legacy_automation():
    """Setup automated legacy management for MarkiTect."""

    # Configure agent with custom settings
    from .legacy.agent import AgentConfig

    config = AgentConfig(
        auto_progression=True,                    # Automatically progress deprecations
        cleanup_unused_days=180,                 # Clean up after 6 months of no usage
        migration_guide_auto_generation=True,    # Generate migration guides
        notification_threshold_days=30,          # Notify 30 days before removal
        max_concurrent_migrations=3,             # Limit concurrent migration assistance
        backup_before_cleanup=True               # Always backup before cleanup
    )

    agent = LegacyAgent(config=config)

    # Schedule regular maintenance (this would typically be done via cron/systemd)
    maintenance_summary = agent.run_maintenance()

    return agent, maintenance_summary


# Example 5: CLI commands for legacy management
# This shows how to add CLI commands for managing legacy interfaces

@click.group('legacy')
def legacy_management():
    """Manage legacy interface compatibility and lifecycle."""
    pass


@legacy_management.command('status')
@click.option('--format', '-f', type=click.Choice(['table', 'json', 'yaml']),
              default='table', help='Output format')
def legacy_status(format):
    """Show status of all legacy interfaces."""
    registry = LegacyRegistry()

    # Get all legacy interfaces
    interfaces = []
    for command in registry._interfaces:
        for version, interface in registry._interfaces[command].items():
            interfaces.append({
                'command': interface.command,
                'version': interface.version,
                'status': interface.status.value,
                'deprecated_date': interface.deprecated_date,
                'removal_date': interface.removal_date,
                'git_commit': interface.git_commit[:8] if interface.git_commit else 'N/A'
            })

    if format == 'json':
        click.echo(json.dumps(interfaces, indent=2))
    elif format == 'yaml':
        import yaml
        click.echo(yaml.dump(interfaces, default_flow_style=False))
    else:
        # Table format
        if interfaces:
            from tabulate import tabulate
            headers = ['Command', 'Version', 'Status', 'Deprecated', 'Removal', 'Commit']
            rows = [[i['command'], i['version'], i['status'],
                    i['deprecated_date'][:10] if i['deprecated_date'] else 'N/A',
                    i['removal_date'][:10] if i['removal_date'] else 'N/A',
                    i['git_commit']] for i in interfaces]
            click.echo(tabulate(rows, headers=headers, tablefmt='grid'))
        else:
            click.echo("No legacy interfaces found.")


@legacy_management.command('migrate')
@click.argument('command')
@click.argument('version')
def legacy_migrate(command, version):
    """Get migration guidance for a legacy version."""
    registry = LegacyRegistry()

    interface = registry.get_legacy_interface(command, version)
    if not interface:
        click.echo(f"Legacy version {command} {version} not found.", err=True)
        return

    migration = registry.get_migration_path(command, version)

    click.echo(f"Migration Guide for {command} {version}")
    click.echo("=" * 50)

    if interface.migration_guide:
        click.echo(interface.migration_guide)
    else:
        click.echo("No specific migration guide available.")

    if migration['breaking_changes']:
        click.echo("\nBreaking Changes:")
        for change in migration['breaking_changes']:
            click.echo(f"• {change}")


@legacy_management.command('cleanup')
@click.argument('command')
@click.argument('version')
@click.option('--force', is_flag=True, help='Force cleanup without confirmation')
def legacy_cleanup(command, version, force):
    """Clean up a specific legacy version."""
    agent = LegacyAgent()

    if not force:
        interface = agent.registry.get_legacy_interface(command, version)
        if interface:
            click.echo(f"About to clean up {command} {version}")
            click.echo(f"Status: {interface.status.value}")
            if interface.removal_date:
                click.echo(f"Scheduled removal: {interface.removal_date}")

            if not click.confirm("Are you sure you want to proceed?"):
                click.echo("Cleanup cancelled.")
                return

    success = agent.force_cleanup(command, version)
    if success:
        click.echo(f"✅ Successfully cleaned up {command} {version}")
    else:
        click.echo(f"❌ Failed to clean up {command} {version}", err=True)


@legacy_management.command('agent-status')
def legacy_agent_status():
    """Show legacy agent status and statistics."""
    agent = LegacyAgent()
    status = agent.get_agent_status()

    click.echo("Legacy Agent Status")
    click.echo("=" * 30)
    click.echo(f"Data Directory: {status['data_directory']}")
    click.echo(f"Total Tasks: {status['tasks']['total']}")
    click.echo(f"Pending Tasks: {status['tasks']['pending']}")
    click.echo(f"Completed Tasks: {status['tasks']['completed']}")

    if status['next_maintenance']:
        click.echo(f"Next Maintenance: {status['next_maintenance']}")

    click.echo("\nRegistry Statistics:")
    for stat_name, stat_value in status['registry_stats'].items():
        click.echo(f"  {stat_name}: {stat_value}")


# Example 6: Integration with existing CLI structure
# This shows how to add legacy support to the main CLI

def add_legacy_support_to_main_cli():
    """
    Example of how to integrate legacy support into the main CLI module.

    This would typically be added to markitect/cli.py
    """

    # 1. Import legacy components at the top of cli.py
    # from .legacy import LegacyRegistry, with_legacy_support, legacy_option

    # 2. Initialize legacy system in the main CLI group
    def initialize_legacy_system():
        # Setup registry and compatibility adapters
        setup_query_legacy_adapters()
        register_query_legacy_versions()

        # Setup agent for automation
        setup_legacy_automation()

    # 3. Add legacy support to existing commands (example for query command)
    def enhance_existing_query_command():
        """
        This shows how to modify the existing query command in cli.py
        to add legacy support without breaking changes.
        """

        # Original command would be modified from:
        # @cli.command()
        # @click.argument('sql', type=str)
        # @click.option('--format', '-f', ...)
        # def query(sql, format):
        #     # existing implementation

        # To:
        # @cli.command()
        # @click.argument('sql', type=str)
        # @click.option('--format', '-f', ...)
        # @legacy_option('v1.0', 'Use v1.0 legacy behavior')
        # @legacy_option('v2.0', 'Use v2.0 legacy behavior')
        # @with_legacy_support('query')
        # def query(sql, format, legacy_v1_0=False, legacy_v2_0=False):
        #     # The @with_legacy_support decorator handles routing
        #     # Original implementation stays the same
        #     return original_query_implementation(sql, format)

        pass

    # 4. Add legacy management commands to main CLI
    def add_legacy_commands_to_cli():
        """Add legacy management commands to main CLI."""

        # This would be added to the main cli group:
        # @cli.group()
        # def legacy():
        #     """Legacy interface management commands."""
        #     pass
        #
        # Then add all the legacy_management commands as subcommands

        pass


if __name__ == '__main__':
    """
    Demonstration of the complete legacy system setup.

    This shows how all components work together.
    """

    click.echo("Setting up MarkiTect Legacy Compatibility System...")

    # 1. Setup compatibility adapters
    click.echo("1. Setting up compatibility adapters...")
    compatibility = setup_query_legacy_adapters()

    # 2. Register legacy versions
    click.echo("2. Registering legacy interfaces...")
    register_query_legacy_versions()

    # 3. Setup automation
    click.echo("3. Setting up legacy automation...")
    agent, summary = setup_legacy_automation()

    # 4. Test legacy functionality
    click.echo("4. Testing legacy compatibility...")

    # Test parameter adaptation
    test_result = compatibility.test_compatibility(
        'query', 'v1.0',
        {'sql_query': 'SELECT * FROM test', 'output_format': 'pretty'}
    )

    if test_result['success']:
        click.echo("   ✅ Parameter adaptation working")
        click.echo(f"   Adapted: {test_result['adapted_parameters']}")
    else:
        click.echo("   ❌ Parameter adaptation failed")

    # Test registry functionality
    registry = LegacyRegistry()
    interface = registry.get_legacy_interface('query', 'v1.0')

    if interface:
        click.echo("   ✅ Legacy interface registry working")
        click.echo(f"   Found: {interface.command} {interface.version} ({interface.status.value})")
    else:
        click.echo("   ❌ Legacy interface registry failed")

    click.echo("\n✅ Legacy compatibility system setup complete!")
    click.echo("\nNext steps:")
    click.echo("1. Integrate legacy_option decorators into existing CLI commands")
    click.echo("2. Add legacy management commands to main CLI")
    click.echo("3. Schedule regular agent maintenance")
    click.echo("4. Monitor legacy usage and plan migrations")