"""
Command-line interface for benchmarking functionality.

This module provides a command-line interface for running parameter
optimization, comparison, and benchmarking tasks.
"""

import argparse

# import logging - replaced with loguru
from loguru import logger
import os
from pathlib import Path
import sys
from datetime import datetime, UTC

from ..config.paths import get_data_directory
from .comparison import compare_configurations
from .efficiency import ResourceMonitor, SpeedProfiler
from .optimization import optimize_parameters

# Configure logging - using loguru instead


def parse_args():
    """Parse command line arguments."""
    parser = argparse.ArgumentParser(
        description="Local Deep Research Benchmarking Tools",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Examples:
  # Run parameter optimization
  python -m local_deep_research.benchmarks.cli optimize "What are the latest advancements in quantum computing?"

  # Compare different configurations
  python -m local_deep_research.benchmarks.cli compare "What are the effects of climate change?" --configs configs.json

  # Run efficiency profiling
  python -m local_deep_research.benchmarks.cli profile "How do neural networks work?"
""",
    )

    subparsers = parser.add_subparsers(dest="command", help="Command to run")

    # Optimizer parser
    optimize_parser = subparsers.add_parser(
        "optimize", help="Optimize parameters"
    )
    optimize_parser.add_argument("query", help="Research query to optimize for")
    optimize_parser.add_argument(
        "--output-dir",
        default=str(get_data_directory() / "optimization_results"),
        help="Directory to save results",
    )
    optimize_parser.add_argument("--model", help="Model name for the LLM")
    optimize_parser.add_argument("--provider", help="Provider for the LLM")
    optimize_parser.add_argument("--search-tool", help="Search tool to use")
    optimize_parser.add_argument(
        "--temperature", type=float, default=0.7, help="LLM temperature"
    )
    optimize_parser.add_argument(
        "--n-trials",
        type=int,
        default=30,
        help="Number of parameter combinations to try",
    )
    optimize_parser.add_argument(
        "--timeout", type=int, help="Maximum seconds to run optimization"
    )
    optimize_parser.add_argument(
        "--n-jobs",
        type=int,
        default=1,
        help="Number of parallel jobs for optimization",
    )
    optimize_parser.add_argument(
        "--study-name", help="Name of the Optuna study"
    )
    optimize_parser.add_argument(
        "--speed-focus", action="store_true", help="Focus optimization on speed"
    )
    optimize_parser.add_argument(
        "--quality-focus",
        action="store_true",
        help="Focus optimization on quality",
    )

    # Comparison parser
    compare_parser = subparsers.add_parser(
        "compare", help="Compare configurations"
    )
    compare_parser.add_argument("query", help="Research query to compare with")
    compare_parser.add_argument(
        "--configs",
        required=True,
        help="JSON file with configurations to compare",
    )
    compare_parser.add_argument(
        "--output-dir",
        default="data/benchmark_results/comparison",
        help="Directory to save results",
    )
    compare_parser.add_argument("--model", help="Model name for the LLM")
    compare_parser.add_argument("--provider", help="Provider for the LLM")
    compare_parser.add_argument("--search-tool", help="Search tool to use")
    compare_parser.add_argument(
        "--repetitions",
        type=int,
        default=1,
        help="Number of repetitions for each configuration",
    )

    # Profiling parser
    profile_parser = subparsers.add_parser(
        "profile", help="Profile resource usage"
    )
    profile_parser.add_argument("query", help="Research query to profile")
    profile_parser.add_argument(
        "--output-dir",
        default="data/benchmark_results/profiling",
        help="Directory to save results",
    )
    profile_parser.add_argument("--model", help="Model name for the LLM")
    profile_parser.add_argument("--provider", help="Provider for the LLM")
    profile_parser.add_argument("--search-tool", help="Search tool to use")
    profile_parser.add_argument(
        "--iterations", type=int, default=2, help="Number of search iterations"
    )
    profile_parser.add_argument(
        "--questions", type=int, default=2, help="Questions per iteration"
    )
    profile_parser.add_argument(
        "--strategy", default="iterdrag", help="Search strategy to use"
    )

    return parser.parse_args()


def run_optimization(args):
    """Run parameter optimization."""
    logger.info(f"Starting parameter optimization for query: {args.query}")

    # Determine metric weights based on focus
    metric_weights = None
    if args.speed_focus:
        metric_weights = {"speed": 0.8, "quality": 0.2}
    elif args.quality_focus:
        metric_weights = {"quality": 0.8, "speed": 0.2}

    # Run optimization
    best_params, best_score = optimize_parameters(
        query=args.query,
        output_dir=args.output_dir,
        model_name=args.model,
        provider=args.provider,
        search_tool=args.search_tool,
        temperature=args.temperature,
        n_trials=args.n_trials,
        timeout=args.timeout,
        n_jobs=args.n_jobs,
        study_name=args.study_name,
        metric_weights=metric_weights,
    )

    # Print results
    print("\nOptimization Results:")
    print("====================")
    print(f"Best Parameters: {best_params}")
    print(f"Best Score: {best_score:.4f}")
    print(f"Results saved to: {args.output_dir}")

    return 0


def run_comparison(args):
    """Run configuration comparison."""
    import json

    logger.info(f"Comparing configurations for query: {args.query}")

    # Load configurations from file
    try:
        with open(args.configs, "r") as f:
            configurations = json.load(f)

        if not isinstance(configurations, list):
            logger.error("Configurations file must contain a JSON array")
            return 1

        if not configurations:
            logger.error("No configurations found in the file")
            return 1
    except Exception:
        logger.exception("Error loading configurations file")
        return 1

    # Run comparison
    results = compare_configurations(
        query=args.query,
        configurations=configurations,
        output_dir=args.output_dir,
        model_name=args.model,
        provider=args.provider,
        search_tool=args.search_tool,
        repetitions=args.repetitions,
    )

    # Print summary
    print("\nComparison Results:")
    print("==================")
    print(f"Configurations tested: {results['configurations_tested']}")
    print(f"Successful configurations: {results['successful_configurations']}")
    print(f"Failed configurations: {results['failed_configurations']}")

    # Print ranking
    print("\nRanking by Overall Score:")
    for i, result in enumerate(
        [r for r in results["results"] if r.get("success", False)]
    ):
        print(
            f"{i + 1}. {result['name']}: {result.get('overall_score', 0):.4f}"
        )

    print(f"\nResults saved to: {results.get('report_path', args.output_dir)}")

    return 0


def run_profiling(args):
    """Run resource profiling."""

    from local_deep_research.config.llm_config import get_llm
    from local_deep_research.config.search_config import get_search
    from local_deep_research.search_system import AdvancedSearchSystem

    logger.info(f"Profiling resource usage for query: {args.query}")

    # Create output directory
    os.makedirs(args.output_dir, exist_ok=True)

    # Initialize profiling tools
    speed_profiler = SpeedProfiler()
    resource_monitor = ResourceMonitor(sampling_interval=0.5)

    # Start profiling
    speed_profiler.start()
    resource_monitor.start()

    llm = None
    search = None
    system = None
    try:
        # Initialize system
        with speed_profiler.timer("initialization"):
            # Get LLM
            llm = get_llm(model_name=args.model, provider=args.provider)

            # Get search engine
            search = None
            if args.search_tool:
                search = get_search(args.search_tool, llm_instance=llm)

            # Create search system
            system = AdvancedSearchSystem(llm=llm, search=search)
            system.max_iterations = args.iterations
            system.questions_per_iteration = args.questions
            system.strategy_name = args.strategy

        # Run analysis
        with speed_profiler.timer("analysis"):
            results = system.analyze_topic(args.query)

        # Stop profiling
        speed_profiler.stop()
        resource_monitor.stop()

        # Get profiling results
        timing_results = speed_profiler.get_summary()
        resource_results = resource_monitor.get_combined_stats()

        # Print summary
        print("\nProfiling Results:")
        print("=================")

        # Timing summary
        print("\nTiming Summary:")
        total_duration = timing_results.get("total_duration", 0)
        print(f"Total execution time: {total_duration:.2f} seconds")

        # Component breakdown
        print("\nComponent Breakdown:")
        for name, value in timing_results.items():
            if name != "total_duration" and name.endswith("_duration"):
                component = name.replace("_duration", "")
                duration = value
                percent = (
                    (duration / total_duration * 100)
                    if total_duration > 0
                    else 0
                )
                print(f"- {component}: {duration:.2f}s ({percent:.1f}%)")

        # Resource summary
        print("\nResource Usage Summary:")
        print(
            f"Peak memory: {resource_results.get('process_memory_max_mb', 0):.1f} MB"
        )
        print(
            f"Average memory: {resource_results.get('process_memory_avg_mb', 0):.1f} MB"
        )
        print(f"Peak CPU: {resource_results.get('process_cpu_max', 0):.1f}%")
        print(f"Average CPU: {resource_results.get('process_cpu_avg', 0):.1f}%")

        # Save results
        from ..security.file_write_verifier import write_json_verified

        timestamp = datetime.now(UTC).strftime("%Y%m%d_%H%M%S")
        results_file = str(
            Path(args.output_dir) / f"profiling_results_{timestamp}.json"
        )

        results_data = {
            "query": args.query,
            "configuration": {
                "model": args.model,
                "provider": args.provider,
                "search_tool": args.search_tool,
                "iterations": args.iterations,
                "questions_per_iteration": args.questions,
                "strategy": args.strategy,
            },
            "timing_results": timing_results,
            "resource_results": resource_results,
            "findings_count": len(results.get("findings", [])),
            "knowledge_length": len(results.get("current_knowledge", "")),
            "timestamp": timestamp,
        }

        write_json_verified(
            results_file,
            results_data,
            "benchmark.allow_file_output",
            context="profiling results",
        )

        print(f"\nDetailed results saved to: {results_file}")

        return 0

    except Exception:
        # Stop profiling on error
        speed_profiler.stop()
        resource_monitor.stop()

        logger.exception("Error during profiling")
        return 1
    finally:
        from ..utilities.resource_utils import safe_close

        safe_close(system, "benchmark system")
        safe_close(search, "benchmark search engine")
        safe_close(llm, "benchmark LLM")


def main():
    """Main entry point for the CLI."""
    args = parse_args()

    if args.command == "optimize":
        return run_optimization(args)
    if args.command == "compare":
        return run_comparison(args)
    if args.command == "profile":
        return run_profiling(args)
    print("Please specify a command. Use --help for more information.")
    return 1


if __name__ == "__main__":
    sys.exit(main())
