#!/bin/bash

# A script to find artists with few tracks and consolidate them under "Various Artists".
#
# Usage:
# ./organize_music.sh /path/to/your/music/library
#
# Dependencies:
# - ffmpeg: A command-line tool to convert, stream, and record audio and video files.
#   You must install it for this script to work. (e.g., `sudo apt install ffmpeg` on Debian/Ubuntu)

# --- Configuration ---
TARGET_DIR="$1"
declare -A artist_counts
declare -A artist_files

# --- Pre-flight Checks ---

# Check if a directory was provided
if [[ -z "$TARGET_DIR" || ! -d "$TARGET_DIR" ]]; then
  echo "Error: Please provide a valid directory."
  echo "Usage: $0 /path/to/your/music"
  exit 1
fi

# Check if ffmpeg is installed
if ! command -v ffmpeg &> /dev/null; then
  echo "Error: ffmpeg is not installed. Please install it to continue."
  exit 1
fi

# --- Main Logic ---

echo "Scanning for audio files in '$TARGET_DIR'..."

# Use `find` to locate all relevant audio files and read them into the script.
# The `while` loop reads each file path provided by `find`.
while IFS= read -r file; do
  # Use ffprobe to get the 'artist' tag from the file's metadata.
  # -v error: Suppresses all output except for errors.
  # -show_entries format_tags=artist: Specifies that we only want the artist tag.
  # -of default=noprint_wrappers=1:nokey=1: Formats the output to be just the value of the tag.
  artist=$(ffprobe -v error -show_entries format_tags=artist -of default=noprint_wrappers=1:nokey=1 "$file")

  # If an artist tag was found and is not empty...
  if [[ -n "$artist" ]]; then
    # Increment the count for this artist.
    ((artist_counts["$artist"]++))
    # Append the file path to a list for this artist, separated by newlines.
    artist_files["$artist"]+="${file}"$'
'
  fi
done < <(find "$TARGET_DIR" -type f \( -iname "*.mp3" -o -iname "*.flac" -o -iname "*.ogg" -o -iname "*.m4a" \))

echo "Scan complete. Found ${#artist_counts[@]} unique artists."
echo "Now checking for artists with 1 or 2 tracks..."

# Loop through all the unique artists we found.
for artist in "${!artist_counts[@]}"; do
  count=${artist_counts["$artist"]}

  # Check if the artist's track count is 2 or less.
  if (( count <= 2 )); then
    echo "--------------------------------------------------"
    echo "Artist '$artist' has only $count track(s). Updating to 'Various Artists'."

    # Read the list of files associated with this artist.
    while IFS= read -r file_to_update; do
      if [[ -n "$file_to_update" ]]; then
        echo "  -> Updating: $file_to_update"
        
        # Create a temporary file path.
        temp_file="${file_to_update}.tmp.${file_to_update##*.}"

        # Use ffmpeg to update the metadata.
        # -i: input file
        # -c copy: Copies the audio stream without re-encoding (fast and preserves quality).
        # -metadata artist="...": Sets the new artist tag.
        # The output is written to the temporary file.
        ffmpeg -i "$file_to_update" -c copy -metadata artist="Various Artists" "$temp_file" -y -hide_banner -loglevel error

        # If the ffmpeg command was successful, replace the original file with the new one.
        if [[ $? -eq 0 ]]; then
          mv "$temp_file" "$file_to_update"
        else
          echo "  -> ERROR: Failed to update metadata for $file_to_update. Skipping."
          # Clean up the temporary file if it exists
          [[ -f "$temp_file" ]] && rm "$temp_file"
        fi
      fi
    done <<< "${artist_files["$artist"]}"
  fi
done

echo "--------------------------------------------------"
echo "Operation complete."
