"""CLI commands for metadata stage."""

import logging
from pathlib import Path
from typing import Optional, Dict, Any

import typer
from rich.console import Console
from rich.table import Table
from rich.panel import Panel

from ..config import MetadataConfig
from ..processor import MetadataProcessor
from src.metadata.services.metadata_orchestrator import MetadataOrchestrator

console = Console()
metadata_app = typer.Typer(help="Metadata allocation commands")


@metadata_app.command("run")
def run_metadata_allocation(
    config: str = typer.Option(..., help="Path to metadata configuration YAML file"),
    month: Optional[str] = typer.Option(None, help="Specific month (YYYY-MM) - optional override"),
    provider: Optional[str] = typer.Option(None, help="Specific provider - optional override"),
    debug: bool = typer.Option(False, help="Enable debug logging for troubleshooting"),
    force: bool = typer.Option(False, "--force", help="Force reprocessing: deletes existing metadata data and reprocesses"),
    api: bool = typer.Option(False, "--api", help="Execute via API - same as default (kept for backward compatibility)"),
    local: bool = typer.Option(False, "--local", help="Execute locally instead of via API (for development/debugging)"),
):
    """
    Process metadata allocation for billing data.

    This command loads your metadata configuration, shows you what will be processed,
    and asks for confirmation before proceeding with the allocation.

    The system processes data one provider-month at a time for memory efficiency
    and applies deterministic allocation for cross-month consistency.

    Execution modes:
    - Default: Submit to Lambda API for processing on ECS workers (scalable, observable)
    - --local: Execute locally for development, debugging, or small datasets
    - --api: Explicit API execution (same as default, kept for backward compatibility)

    Examples:
        czbillgen metadata run --config configs/metadata/config.metadata.yaml
        czbillgen metadata run --config configs/metadata/config.metadata.yaml --local
        czbillgen metadata run --config configs/metadata/config.metadata.yaml --month 2024-01
        czbillgen metadata run --config configs/metadata/config.metadata.yaml --provider aws --debug --local
    """
    # Validate mutually exclusive flags
    if api and local:
        console.print("[red]❌ Cannot specify both --api and --local[/red]")
        raise typer.Exit(1)

    # Execute locally if --local flag provided
    if local:
        console.print("[dim]⚙️  Executing locally...[/dim]")
        _execute_metadata_locally(config, month, provider, debug, force)
        return

    # Default: Execute via API
    console.print("[cyan]☁️  Executing via API (Lambda + ECS workers)...[/cyan]")
    from pathlib import Path
    from src.api.cli_helper import execute_stage_via_api

    execute_stage_via_api(
        job_type="metadata",
        config_path=Path(config),
        month=month,
        provider=provider,
        force=force,
    )


def _execute_metadata_locally(
    config: str,
    month: Optional[str],
    provider: Optional[str],
    debug: bool,
    force: bool
):
    """Execute metadata allocation locally."""

    try:
        # Configure debug logging if requested
        if debug:
            logging.basicConfig(level=logging.DEBUG)
            console.print("🔍 [yellow]Debug logging enabled[/yellow]")

        # Step 1: Load and validate configuration
        console.print("🚀 [bold green]Metadata Allocation Starting[/bold green]")
        console.print("📋 Loading configuration...")

        metadata_config = MetadataConfig.from_yaml(config)
        orchestrator = MetadataOrchestrator(metadata_config)

        # Step 2: Show configuration summary and get user confirmation
        if not _show_configuration_and_confirm(metadata_config, orchestrator):
            console.print("❌ [yellow]Processing cancelled by user[/yellow]")
            raise typer.Exit(0)

        # Step 3: Validate prerequisites
        validation_errors = orchestrator.validate_prerequisites()
        if validation_errors:
            console.print("❌ [red]Prerequisites validation failed:[/red]")
            for error in validation_errors:
                console.print(f"   • {error}")
            raise typer.Exit(1)

        # Step 4: Run metadata allocation
        console.print("🔄 [bold blue]Starting metadata processing...[/bold blue]")

        try:
            summary = orchestrator.run_metadata_allocation(provider=provider, month=month, force=force)

            # Display results
            _display_processing_results(summary)

            if summary["processing_stats"]["processing_errors"] > 0:
                console.print("⚠️  [yellow]Processing completed with some errors[/yellow]")
                raise typer.Exit(1)
            else:
                console.print("✅ [bold green]Metadata allocation completed successfully![/bold green]")

        except Exception as e:
            console.print(f"❌ [red]Processing failed: {e}[/red]")
            if debug:
                import traceback
                console.print(traceback.format_exc())
            raise typer.Exit(1)

    except FileNotFoundError as e:
        console.print(f"❌ [red]Configuration file not found: {e}[/red]")
        raise typer.Exit(1)

    except ValueError as e:
        console.print(f"❌ [red]Configuration error: {e}[/red]")
        raise typer.Exit(1)

    except Exception as e:
        console.print(f"❌ [red]Unexpected error: {e}[/red]")
        if debug:
            import traceback
            console.print(traceback.format_exc())
        raise typer.Exit(1)


def _show_configuration_and_confirm(
    config: MetadataConfig,
    orchestrator: MetadataOrchestrator
) -> bool:
    """
    Show configuration summary and get user confirmation.

    Args:
        config: Loaded metadata configuration
        orchestrator: Initialized metadata orchestrator

    Returns:
        True if user confirms processing, False otherwise
    """
    # Show dataset info
    console.print(f"📊 [bold]Dataset:[/bold] {config.dataset_name}")
    console.print(f"🏢 [bold]Providers configured:[/bold] {len(config.providers)}")

    # Get processing summary
    console.print("🔍 [dim]Querying S3 for available months...[/dim]")
    processing_summary = orchestrator.get_processing_summary()
    console.print("✓ [dim]S3 query complete[/dim]")

    # Create detailed configuration table
    table = Table(title="Provider Configuration Details", show_header=True, header_style="bold magenta")
    table.add_column("Provider", style="cyan", no_wrap=True)
    table.add_column("Key", style="green")
    table.add_column("Values", style="yellow")
    table.add_column("Type", style="blue")

    for provider_config in config.providers:
        processor_summary = processing_summary["processor_details"].get(provider_config.provider, {})

        if not processor_summary.get("configured", False):
            continue

        processing_types = processor_summary.get("processing_types", {})

        # Add region keys
        for key_info in processing_types.get("region_keys", []):
            table.add_row(
                provider_config.provider,
                key_info["key"],
                str(key_info["values_count"]),
                "Region (Special Case)"
            )

        # Add account keys
        for key_info in processing_types.get("account_keys", []):
            table.add_row(
                provider_config.provider,
                key_info["key"],
                str(key_info["values_count"]),
                "Account (Special Case)"
            )

        # Add tags-only keys
        for key_info in processing_types.get("tags_only_keys", []):
            table.add_row(
                provider_config.provider,
                key_info["key"],
                str(key_info["values_count"]),
                "Tags-Only"
            )

        # Add k8s-labels-only keys
        for key_info in processing_types.get("k8s_labels_only_keys", []):
            table.add_row(
                provider_config.provider,
                key_info["key"],
                str(key_info["values_count"]),
                "K8s-Labels-Only"
            )

        # Add resource-id-only keys
        for key_info in processing_types.get("resource_id_only_keys", []):
            table.add_row(
                provider_config.provider,
                key_info["key"],
                str(key_info["values_count"]),
                "Resource-ID-Only"
            )

        # Add four-group keys
        for key_info in processing_types.get("four_group_keys", []):
            table.add_row(
                provider_config.provider,
                key_info["key"],
                str(key_info["values_count"]),
                "Four-Group"
            )

        # Add correlated groups
        if provider_config.correlated_groups:
            for i, group in enumerate(provider_config.correlated_groups, 1):
                if group.tags_only:
                    group_type = "Correlated (Tags-Only)"
                elif group.k8s_labels_only:
                    group_type = "Correlated (K8s-Labels-Only)"
                elif group.resource_id_only:
                    group_type = "Correlated (Resource-ID-Only)"
                else:
                    group_type = "Correlated (Four-Group)"
                key_names = ", ".join(list(group.keys.keys())[:2])  # Show first 2 keys
                if len(group.keys) > 2:
                    key_names += f", +{len(group.keys) - 2} more"

                first_key_values = list(group.keys.values())[0] if group.keys else []
                table.add_row(
                    provider_config.provider,
                    f"Group {i}: {key_names}",
                    f"{len(first_key_values)} sets",
                    group_type
                )

    console.print(table)

    # Show data availability summary
    _show_data_availability_summary(processing_summary)

    # Show processing explanation
    explanation_panel = Panel(
        "[bold]Processing Types:[/bold]\n\n"
        "• [blue]Region (Special Case)[/blue]: Updates 'region' column directly\n"
        "• [cyan]Account (Special Case)[/cyan]: Updates 'cloud_account' column and provider-specific tags\n"
        "• [green]Tags-Only[/green]: All resources get 'resource/tag:{provider}:{key}' columns\n"
        "• [magenta]K8s-Labels-Only[/magenta]: Only K8s resources get k8s_labels JSON updates\n"
        "• [red]Resource-ID-Only[/red]: All resources get resource_id modifications only\n"
        "• [yellow]Four-Group[/yellow]: Resources split into 4 groups (tags, resource IDs, K8s labels, K8s namespaces)\n"
        "• [purple]Correlated[/purple]: Multiple keys allocated together using index-based correlation\n\n"
        "[bold]Cross-Month Consistency:[/bold] Same resources get same values across all months",
        title="ℹ️ How It Works",
        border_style="blue"
    )
    console.print(explanation_panel)

    # Warning about mistyped providers
    configured_providers = [p.provider for p in config.providers]
    console.print(f"⚠️  [yellow]Only these providers will be processed:[/yellow] {configured_providers}")
    console.print("   [dim]If you mistyped a provider name, it will be silently skipped[/dim]")

    # Get user confirmation
    return typer.confirm("\n🚀 Proceed with metadata processing?")


def _show_data_availability_summary(processing_summary: Dict[str, Any]):
    """Show data availability summary."""
    if "error" in processing_summary:
        console.print(f"⚠️  [yellow]Could not check data availability: {processing_summary['error']}[/yellow]")
        return

    # Create data availability table
    data_table = Table(title="Data Availability Summary", show_header=True, header_style="bold cyan")
    data_table.add_column("Metric", style="white")
    data_table.add_column("Count", style="green")

    data_table.add_row("Total provider-months available", str(processing_summary.get("total_combinations", 0)))
    data_table.add_row("Processing candidates", str(processing_summary.get("processing_candidates", 0)))
    data_table.add_row("Already completed", str(processing_summary.get("completed_combinations", 0)))
    # Note: Removed expensive "Total rows available" calculation for faster initialization

    console.print(data_table)

    # Show providers and months
    providers = processing_summary.get("providers", [])
    months = processing_summary.get("months", [])

    if providers:
        console.print(f"📊 [bold]Available providers:[/bold] {', '.join(providers)}")
    if months:
        console.print(f"📅 [bold]Available months:[/bold] {', '.join(months)}")

    # Show data sources
    data_sources = processing_summary.get("data_sources", {})
    if data_sources:
        k8s_count = data_sources.get("k8s", 0)
        generate_count = data_sources.get("generate", 0)
        console.print(f"🔄 [bold]Data sources:[/bold] k8s stage ({k8s_count}), generate stage ({generate_count})")


def _display_processing_results(summary: Dict[str, Any]):
    """Display processing results summary."""
    stats = summary.get("processing_stats", {})
    coverage = summary.get("coverage", {})

    # Create results table
    results_table = Table(title="Processing Results", show_header=True, header_style="bold green")
    results_table.add_column("Metric", style="white")
    results_table.add_column("Count", style="cyan")

    results_table.add_row("Total candidates", str(stats.get("total_candidates", 0)))
    results_table.add_row("Processed successfully", str(stats.get("processed_successfully", 0)))
    results_table.add_row("Processing errors", str(stats.get("processing_errors", 0)))
    results_table.add_row("Validation errors", str(stats.get("validation_errors", 0)))
    results_table.add_row("Total rows processed", f"{stats.get('total_rows_processed', 0):,}")

    console.print(results_table)

    # Show coverage details
    providers_processed = coverage.get("providers_processed", [])
    months_processed = coverage.get("months_processed", [])

    if providers_processed:
        console.print(f"📊 [bold]Providers processed:[/bold] {', '.join(providers_processed)}")
    if months_processed:
        console.print(f"📅 [bold]Months processed:[/bold] {', '.join(months_processed)}")

    # Show status
    status = summary.get("status", "Unknown")
    if status == "Completed":
        if stats.get("processing_errors", 0) == 0:
            console.print("✅ [bold green]All processing completed successfully[/bold green]")
        else:
            console.print("⚠️  [yellow]Processing completed with errors - check logs for details[/yellow]")
    else:
        console.print(f"ℹ️  [blue]Status: {status}[/blue]")


@metadata_app.command("validate")
def validate_configuration(
    config: str = typer.Option(..., help="Path to metadata configuration YAML file"),
):
    """
    Validate metadata configuration without processing.

    Loads the configuration file and validates its structure, showing
    detailed information about what would be processed.

    Example:
        czbillgen metadata validate --config configs/metadata/config.metadata.yaml
    """
    try:
        console.print("🔍 [bold blue]Validating Metadata Configuration[/bold blue]")

        # Load configuration
        metadata_config = MetadataConfig.from_yaml(config)
        orchestrator = MetadataOrchestrator(metadata_config)

        console.print("✅ [green]Configuration loaded successfully[/green]")

        # Validate prerequisites
        validation_errors = orchestrator.validate_prerequisites()
        if validation_errors:
            console.print("⚠️  [yellow]Prerequisites validation found issues:[/yellow]")
            for error in validation_errors:
                console.print(f"   • {error}")
        else:
            console.print("✅ [green]Prerequisites validation passed[/green]")

        # Show configuration details
        _show_configuration_details(metadata_config, orchestrator)

        console.print("✅ [bold green]Configuration validation completed![/bold green]")

    except FileNotFoundError as e:
        console.print(f"❌ [red]Configuration file not found: {e}[/red]")
        raise typer.Exit(1)

    except ValueError as e:
        console.print(f"❌ [red]Configuration error: {e}[/red]")
        raise typer.Exit(1)

    except Exception as e:
        console.print(f"❌ [red]Unexpected validation error: {e}[/red]")
        raise typer.Exit(1)


def _show_configuration_details(config: MetadataConfig, orchestrator: MetadataOrchestrator):
    """Show detailed configuration information."""
    console.print(f"📊 [bold]Dataset:[/bold] {config.dataset_name}")
    console.print(f"🏢 [bold]Providers:[/bold] {len(config.providers)}")

    # Get processing summary for detailed information
    processing_summary = orchestrator.get_processing_summary()
    processor_details = processing_summary.get("processor_details", {})

    for provider_config in config.providers:
        console.print(f"\n[bold cyan]{provider_config.provider.upper()}[/bold cyan]:")

        # Get processor summary for this provider
        processor_summary = processor_details.get(provider_config.provider, {})

        for key_config in provider_config.keys:
            # Determine processing type
            processing_type = "Four-Group"  # Default
            if processor_summary.get("configured", False):
                processing_types = processor_summary.get("processing_types", {})

                # Check if it's a region key
                region_keys = [k["key"] for k in processing_types.get("region_keys", [])]
                if key_config.key_name in region_keys:
                    processing_type = "Region"
                else:
                    # Check if it's an account key
                    account_keys = [k["key"] for k in processing_types.get("account_keys", [])]
                    if key_config.key_name in account_keys:
                        processing_type = "Account"
                    elif key_config.tags_only:
                        processing_type = "Tags-Only"
                    elif key_config.k8s_labels_only:
                        processing_type = "K8s-Labels-Only"
                    elif key_config.resource_id_only:
                        processing_type = "Resource-ID-Only"

            console.print(f"  • [green]{key_config.key_name}[/green]: {len(key_config.values)} values ({processing_type})")

            # Show first few values as examples
            example_values = key_config.values[:3]
            if len(key_config.values) > 3:
                example_values.append(f"... +{len(key_config.values) - 3} more")

            console.print(f"    Values: {', '.join(example_values)}")

        # Show correlated groups
        if provider_config.correlated_groups:
            console.print(f"\n  [bold magenta]Correlated Groups:[/bold magenta] {len(provider_config.correlated_groups)}")
            for i, group in enumerate(provider_config.correlated_groups, 1):
                if group.tags_only:
                    processing_type = "Tags-Only"
                elif group.k8s_labels_only:
                    processing_type = "K8s-Labels-Only"
                elif group.resource_id_only:
                    processing_type = "Resource-ID-Only"
                else:
                    processing_type = "Four-Group"
                console.print(f"  • [purple]Group {i}[/purple]: {len(group.keys)} keys ({processing_type})")

                # Show keys in this group
                key_names = list(group.keys.keys())
                console.print(f"    Keys: {', '.join(key_names)}")

                # Show correlation set count
                first_key_values = list(group.keys.values())[0] if group.keys else []
                console.print(f"    Correlation sets: {len(first_key_values)}")

    # Show data availability if available
    if "error" not in processing_summary:
        console.print(f"\n📈 [bold]Data Availability:[/bold]")
        _show_data_availability_summary(processing_summary)


@metadata_app.command("status")
def show_processing_status(
    config: str = typer.Option(..., help="Path to metadata configuration YAML file"),
    provider: Optional[str] = typer.Option(None, help="Specific provider filter"),
    month: Optional[str] = typer.Option(None, help="Specific month filter")
):
    """
    Show current processing status and data availability.

    Shows what data is available, what has been completed, and what
    still needs processing. Useful for monitoring progress and planning
    next steps.

    Examples:
        czbillgen metadata status --config configs/metadata/config.metadata.yaml
        czbillgen metadata status --config configs/metadata/config.metadata.yaml --provider aws
        czbillgen metadata status --config configs/metadata/config.metadata.yaml --month 2024-01
    """
    try:
        console.print("📊 [bold blue]Metadata Processing Status[/bold blue]")

        # Load configuration
        metadata_config = MetadataConfig.from_yaml(config)
        orchestrator = MetadataOrchestrator(metadata_config)

        # Get comprehensive processing summary
        console.print("🔍 Analyzing data availability...")
        summary = orchestrator.get_processing_summary(provider, month, force=True)

        # Display status overview
        _display_status_overview(summary)

        # Display detailed completion status
        _display_completion_status(summary)

    except FileNotFoundError as e:
        console.print(f"❌ [red]Configuration file not found: {e}[/red]")
        raise typer.Exit(1)

    except Exception as e:
        console.print(f"❌ [red]Status check failed: {e}[/red]")
        raise typer.Exit(1)


@metadata_app.command("resume")
def resume_processing(
    config: str = typer.Option(..., help="Path to metadata configuration YAML file"),
    provider: Optional[str] = typer.Option(None, help="Resume specific provider only"),
    month: Optional[str] = typer.Option(None, help="Resume specific month only"),
    debug: bool = typer.Option(False, help="Enable debug logging")
):
    """
    Resume incomplete metadata processing.

    Automatically detects what work remains to be done and continues
    processing from where it left off. Only processes provider-months
    that haven't been completed yet.

    Examples:
        czbillgen metadata resume --config configs/metadata/config.metadata.yaml
        czbillgen metadata resume --config configs/metadata/config.metadata.yaml --provider aws
        czbillgen metadata resume --config configs/metadata/config.metadata.yaml --debug
    """
    try:
        if debug:
            logging.basicConfig(level=logging.DEBUG)
            console.print("🔍 [yellow]Debug logging enabled[/yellow]")

        console.print("🔄 [bold blue]Resuming Metadata Processing[/bold blue]")

        # Load configuration
        metadata_config = MetadataConfig.from_yaml(config)
        orchestrator = MetadataOrchestrator(metadata_config)

        # Check what needs processing (force=False to skip completed)
        console.print("🔍 Checking for incomplete work...")
        summary = orchestrator.get_processing_summary(provider, month, force=False)

        candidates_count = summary.get("processing_candidates", 0)
        if candidates_count == 0:
            console.print("✅ [green]All work is already complete! Nothing to resume.[/green]")
            return

        console.print(f"📋 Found {candidates_count} provider-months to process")

        # Validate prerequisites
        validation_errors = orchestrator.validate_prerequisites()
        if validation_errors:
            console.print("❌ [red]Prerequisites validation failed:[/red]")
            for error in validation_errors:
                console.print(f"   • {error}")
            raise typer.Exit(1)

        # Confirm resume
        if not typer.confirm("🚀 Resume processing?"):
            console.print("❌ [yellow]Resume cancelled by user[/yellow]")
            raise typer.Exit(0)

        # Resume processing (force=False to skip completed)
        console.print("🔄 [bold blue]Resuming processing...[/bold blue]")
        result_summary = orchestrator.run_metadata_allocation(provider=provider, month=month, force=False)

        # Display results
        _display_processing_results(result_summary)

        if result_summary["processing_stats"]["processing_errors"] > 0:
            console.print("⚠️  [yellow]Resume completed with some errors[/yellow]")
            raise typer.Exit(1)
        else:
            console.print("✅ [bold green]Resume completed successfully![/bold green]")

    except FileNotFoundError as e:
        console.print(f"❌ [red]Configuration file not found: {e}[/red]")
        raise typer.Exit(1)

    except Exception as e:
        console.print(f"❌ [red]Resume failed: {e}[/red]")
        if debug:
            import traceback
            console.print(traceback.format_exc())
        raise typer.Exit(1)


def _display_status_overview(summary: Dict[str, Any]):
    """Display high-level status overview."""
    if "error" in summary:
        console.print(f"❌ [red]Status check failed: {summary['error']}[/red]")
        return

    # Overview table
    overview_table = Table(title="Processing Overview", show_header=True, header_style="bold magenta")
    overview_table.add_column("Metric", style="white")
    overview_table.add_column("Count", style="cyan")
    overview_table.add_column("Status", style="green")

    total = summary.get("total_combinations", 0)
    completed = summary.get("completed_combinations", 0)
    candidates = summary.get("processing_candidates", 0)

    overview_table.add_row("Total provider-months", str(total), "Available")
    overview_table.add_row("Completed", str(completed), "✅ Done")
    overview_table.add_row("Remaining", str(candidates), "🔄 Pending" if candidates > 0 else "✅ All done")

    console.print(overview_table)

    # Progress calculation
    if total > 0:
        progress = (completed / total) * 100
        console.print(f"📊 [bold]Overall Progress:[/bold] {progress:.1f}% ({completed}/{total})")

        if progress == 100:
            console.print("🎉 [bold green]All processing is complete![/bold green]")
        elif progress > 0:
            console.print(f"🔄 [yellow]{candidates} provider-months remaining[/yellow]")
        else:
            console.print("🚀 [blue]Ready to start processing[/blue]")


def _display_completion_status(summary: Dict[str, Any]):
    """Display detailed completion status by validation results."""
    validation_results = summary.get("validation_results", [])
    if not validation_results:
        return

    # Group by provider
    by_provider = {}
    for result in validation_results:
        provider = result["provider"]
        if provider not in by_provider:
            by_provider[provider] = {"completed": 0, "pending": 0, "errors": 0, "months": []}

        if result["valid"]:
            # Check if this month is already completed by looking at data service
            month = result["month"]
            by_provider[provider]["months"].append({
                "month": month,
                "status": "pending",  # We'd need to check completion status here
                "rows": result.get("row_count", 0),
                "errors": result.get("errors", [])
            })
            by_provider[provider]["pending"] += 1
        else:
            by_provider[provider]["errors"] += 1
            by_provider[provider]["months"].append({
                "month": result["month"],
                "status": "error",
                "rows": 0,
                "errors": result.get("errors", [])
            })

    # Display by provider
    for provider, info in by_provider.items():
        console.print(f"\n[bold cyan]{provider.upper()}[/bold cyan]:")

        # Separate error months from pending months
        error_months = [m for m in info["months"] if m["status"] == "error"]
        pending_months = [m for m in info["months"] if m["status"] == "pending"]

        # Show validation errors first with details
        if error_months:
            console.print(f"  ❌ [red]{len(error_months)} months with validation errors[/red]")
            for month_info in error_months:
                console.print(f"    ❌ {month_info['month']}")
                # Show all errors for failed months
                if month_info["errors"]:
                    for error in month_info["errors"]:
                        console.print(f"      ⚠️  [red]{error}[/red]")
                else:
                    console.print(f"      ⚠️  [red]Unknown validation error[/red]")

        # Show pending months
        if pending_months:
            console.print(f"  🔄 [yellow]{len(pending_months)} months ready for processing[/yellow]")
            # Show first 5 pending months as examples
            for month_info in pending_months[:5]:
                row_info = f" ({month_info['rows']:,} rows)" if month_info["rows"] > 0 else ""
                console.print(f"    🔄 {month_info['month']}{row_info}")

            if len(pending_months) > 5:
                console.print(f"    ... and {len(pending_months) - 5} more months")


if __name__ == "__main__":
    metadata_app()