"""
agmem fsck - File system consistency check.
"""

import argparse
from pathlib import Path

from ..commands.base import require_repo


class FsckCommand:
    """Check and repair repository consistency."""
    
    name = 'fsck'
    help = 'Check and repair repository consistency (remove dangling vectors)'
    
    @staticmethod
    def add_arguments(parser: argparse.ArgumentParser):
        parser.add_argument(
            '--dry-run',
            action='store_true',
            help='Show what would be done without making changes'
        )
        parser.add_argument(
            '--verbose', '-v',
            action='store_true',
            help='Show detailed output'
        )
        parser.add_argument(
            '--fix',
            action='store_true',
            help='Actually remove dangling entries (required to make changes)'
        )
    
    @staticmethod
    def execute(args) -> int:
        repo, code = require_repo()
        if code != 0:
            return code
        
        print("Running file system consistency check...")
        
        issues_found = 0
        issues_fixed = 0
        
        # Check vector store for dangling entries
        try:
            from ..core.vector_store import VectorStore
            vs = VectorStore(repo.root / '.mem')
            
            vector_issues, vector_fixed = FsckCommand._check_vectors(
                repo, vs, args.dry_run, args.verbose, args.fix
            )
            issues_found += vector_issues
            issues_fixed += vector_fixed
        except ImportError:
            if args.verbose:
                print("Vector store not available, skipping vector check")
        except Exception as e:
            print(f"Warning: Vector store check failed: {e}")
        
        # Check object store integrity
        obj_issues, obj_fixed = FsckCommand._check_objects(
            repo, args.dry_run, args.verbose, args.fix
        )
        issues_found += obj_issues
        issues_fixed += obj_fixed
        
        # Check refs integrity
        ref_issues, ref_fixed = FsckCommand._check_refs(
            repo, args.dry_run, args.verbose, args.fix
        )
        issues_found += ref_issues
        issues_fixed += ref_fixed
        
        # Print summary
        print()
        print("=" * 40)
        print("FSCK Summary")
        print("=" * 40)
        print(f"Issues found: {issues_found}")
        
        if args.fix:
            print(f"Issues fixed: {issues_fixed}")
        elif issues_found > 0:
            print("\nRun with --fix to repair issues")
        
        if issues_found == 0:
            print("Repository is healthy!")
        
        return 0 if issues_found == 0 else 1
    
    @staticmethod
    def _check_vectors(repo, vs, dry_run: bool, verbose: bool, fix: bool) -> tuple:
        """Check for dangling vector entries."""
        print("\nChecking vector store...")
        
        current_dir = repo.root / 'current'
        entries = vs.get_all_entries()
        
        dangling = []
        
        for entry in entries:
            path = entry['path']
            full_path = current_dir / path
            
            if not full_path.exists():
                dangling.append(entry)
                if verbose:
                    print(f"  Dangling: {path} (rowid: {entry['rowid']})")
        
        if dangling:
            print(f"  Found {len(dangling)} dangling vector entries")
            
            if fix and not dry_run:
                fixed = 0
                for entry in dangling:
                    if vs.delete_entry(entry['rowid']):
                        fixed += 1
                print(f"  Removed {fixed} dangling entries")
                return len(dangling), fixed
            elif dry_run:
                print("  (dry-run: no changes made)")
        else:
            print("  Vector store is consistent")
        
        return len(dangling), 0
    
    @staticmethod
    def _check_objects(repo, dry_run: bool, verbose: bool, fix: bool) -> tuple:
        """Check object store integrity."""
        print("\nChecking object store...")
        
        issues = 0
        
        # Check if all referenced blobs exist
        for obj_type in ['blob', 'tree', 'commit', 'tag']:
            obj_dir = repo.root / '.mem' / 'objects' / obj_type
            if not obj_dir.exists():
                continue
            
            for prefix_dir in obj_dir.iterdir():
                if not prefix_dir.is_dir():
                    continue
                for obj_file in prefix_dir.iterdir():
                    try:
                        # Try to read and decompress
                        import zlib
                        compressed = obj_file.read_bytes()
                        zlib.decompress(compressed)
                    except Exception as e:
                        issues += 1
                        if verbose:
                            hash_id = prefix_dir.name + obj_file.name
                            print(f"  Corrupted {obj_type}: {hash_id[:8]}...")
        
        if issues == 0:
            print("  Object store is consistent")
        else:
            print(f"  Found {issues} corrupted objects")
        
        return issues, 0  # Object repair not implemented
    
    @staticmethod
    def _check_refs(repo, dry_run: bool, verbose: bool, fix: bool) -> tuple:
        """Check refs integrity."""
        print("\nChecking refs...")
        
        issues = 0
        
        # Check if HEAD points to valid commit
        head = repo.refs.get_head()
        if head['type'] == 'branch':
            branch_commit = repo.refs.get_branch_commit(head['value'])
            if not branch_commit:
                issues += 1
                if verbose:
                    print(f"  HEAD branch '{head['value']}' has no commit")
            elif not repo.object_store.exists(branch_commit, 'commit'):
                issues += 1
                if verbose:
                    print(f"  HEAD points to missing commit: {branch_commit[:8]}")
        elif head['type'] == 'detached':
            if not repo.object_store.exists(head['value'], 'commit'):
                issues += 1
                if verbose:
                    print(f"  Detached HEAD points to missing commit")
        
        # Check all branches
        branches = repo.refs.list_branches()
        for branch in branches:
            commit_hash = repo.refs.get_branch_commit(branch)
            if commit_hash and not repo.object_store.exists(commit_hash, 'commit'):
                issues += 1
                if verbose:
                    print(f"  Branch '{branch}' points to missing commit")
        
        if issues == 0:
            print("  Refs are consistent")
        else:
            print(f"  Found {issues} ref issues")
        
        return issues, 0
