"""Analyze command implementation.""" from pathlib import Path from typing import Optional import click from vlm.analysis import analyze_series_completeness, detect_duplicates from vlm.context import CLIContext from vlm.io import ( identities_to_analysis_input, load_identities_json, load_inventory_csv, save_analysis_json, ) from vlm.models import ( AnalysisCompletenessRecord, AnalysisDuplicateIdentityRecord, AnalysisDuplicateRecord, MovieIdentity, SeriesIdentity, ) def analyze_cmd( ctx: CLIContext, input: Path, output: Path, inventory: Optional[Path], ) -> None: """Run analysis: completeness and duplicate detection.""" config = ctx.config logger = ctx.logger click.echo(f"Analyzing identities from: {input}") if inventory: click.echo(f"Merging metadata from inventory: {inventory}") click.echo() identities_data = load_identities_json(input) movies_data = identities_data.get("movies", []) series_data = identities_data.get("series", []) click.echo(f"Loaded {len(movies_data)} movies and {len(series_data)} series") click.echo() inventory_files = load_inventory_csv(inventory) if inventory else None movie_pairs, series_pairs = identities_to_analysis_input( identities_data, inventory_files=inventory_files ) series_identities = [identity for identity, _ in series_pairs] click.echo("Analyzing series completeness...") completeness_results = analyze_series_completeness(series_identities) click.echo("Detecting duplicates...") identity_file_pairs = movie_pairs + series_pairs duplicate_groups = detect_duplicates(identity_file_pairs) click.echo() click.echo("Analysis complete!") click.echo() click.echo("Results:") click.echo(f" Series with episode gaps: {len(completeness_results)}") if completeness_results: total_missing = sum(len(c.episodes_missing) for c in completeness_results) click.echo(f" - Total missing episodes: {total_missing}") click.echo(f" Duplicate groups found: {len(duplicate_groups)}") if duplicate_groups: total_duplicates = sum(len(g.files) for g in duplicate_groups) click.echo(f" - Total duplicate files: {total_duplicates}") click.echo() click.echo(f"Saving analysis results to: {output}") output.parent.mkdir(parents=True, exist_ok=True) completeness_list: list[AnalysisCompletenessRecord] = [ { "series_title": c.series_title, "season": c.season, "episodes_found": c.episodes_found, "episodes_missing": c.episodes_missing, } for c in completeness_results ] duplicates_list: list[AnalysisDuplicateRecord] = [] for d in duplicate_groups: if isinstance(d.identity, MovieIdentity): identity_info: AnalysisDuplicateIdentityRecord = { "type": "movie", "title": d.identity.title, "year": d.identity.year, "season": None, "episodes": [], } else: identity_info = { "type": "series", "title": d.identity.title, "year": None, "season": d.identity.season, "episodes": d.identity.episodes, } duplicates_list.append( { "identity": identity_info, "files": [str(f.path) for f in d.files], "quality_comparison": d.quality_comparison, } ) save_analysis_json( completeness=completeness_list, duplicates=duplicates_list, source_identities=input, total_movies=len(movies_data), total_series=len(series_data), output=output, ) click.echo("Analysis results saved successfully!") logger.info( f"Analysis completed: {len(completeness_results)} incomplete series, " f"{len(duplicate_groups)} duplicate groups, saved to {output}" )