#!/usr/bin/env python3
"""Bulk-rename music files in-place using ID3 tags via mutagen.

Reads artist/title from file metadata and renames to `Artist - Title.ext`.
Handles collisions, special characters, and files already correctly named.

Usage:
    python3 bulk-rename.py /path/to/music/dir

Place in ~/.hermes/skills/media/music-library-management/scripts/
"""

import os
import sys
from mutagen import File

def sanitize(name):
    return name.replace('/', '-').replace('\x00', '')

def rename_tree(base):
    renamed = 0
    skipped_tag = 0
    skipped_ok = 0
    errors = []

    for root, dirs, files in os.walk(base):
        for fname in files:
            if not fname.lower().endswith(('.mp3', '.flac', '.m4a', '.ogg')):
                continue

            fullpath = os.path.join(root, fname)

            try:
                audio = File(fullpath, easy=True)
            except Exception as e:
                errors.append(f"READ {fullpath}: {e}")
                continue

            if audio is None or not audio.tags:
                skipped_tag += 1
                continue

            artist = audio.tags.get('artist', [None])[0]
            title = audio.tags.get('title', [None])[0]

            if not artist or not title:
                skipped_tag += 1
                continue

            ext = os.path.splitext(fname)[1]
            new_name = f"{sanitize(artist)} - {sanitize(title)}{ext}"
            new_path = os.path.join(root, new_name)

            if fullpath == new_path:
                skipped_ok += 1
                continue

            # Handle collisions
            counter = 1
            while os.path.exists(new_path) and new_path != fullpath:
                name_no_ext = f"{sanitize(artist)} - {sanitize(title)} ({counter})"
                new_path = os.path.join(root, name_no_ext + ext)
                counter += 1

            try:
                os.rename(fullpath, new_path)
                renamed += 1
            except OSError as e:
                errors.append(f"RENAME {fullpath}: {e}")

    print(f"Renamed: {renamed}")
    print(f"Skipped (no tags): {skipped_tag}")
    print(f"Skipped (already correct): {skipped_ok}")
    print(f"Errors: {len(errors)}")
    for e in errors[:20]:
        print(f"  {e}")

if __name__ == '__main__':
    if len(sys.argv) < 2:
        print(f"Usage: {sys.argv[0]} /path/to/music/dir")
        sys.exit(1)
    rename_tree(sys.argv[1])
