#!/usr/bin/env bash

# Author: Urpagin
#
# Date: 2025-08-18
#
# License: MIT License, Copyright (c) 2025 Urpagin
#
# File: dl
#
# Description: thin wrapper around yt-dlp that adds simple flags to
# download audio and video with best quality and filename sanitization.

set -euo pipefail

# Which binary of yt-dlp to use
readonly YT_BIN='yt-dlp'
# Which binary of Python to use
readonly PY_BIN='python3'
# Where to create the py venv
readonly PY_VENV_INSTALL_DIR="$HOME/.venvs/dl"
# What py libs to install and make available for yt-dlp to use
readonly PY_LIBS=( mutagen )


if ! command -v "$YT_BIN" >/dev/null 2>&1; then
  printf 'error: missing %s\n' "$YT_BIN"
  exit 1
fi

_usage_exit() {
  printf 'usage: %s [-a URL | -v URL | yt-dlp [yt-dlp opts]]\n' "$0" >&2
  exit 64
}

_install_py_deps() {
  # Python does the mkdir -p for us
  [[ -d "$PY_VENV_INSTALL_DIR" ]] || "$PY_BIN" -m venv "$PY_VENV_INSTALL_DIR"

  # shellcheck disable=SC1091
  source "${PY_VENV_INSTALL_DIR}/bin/activate"

  pip install -U "${PY_LIBS[@]}" >/dev/null 2>&1 || printf 'error: failed to install Python dependencies\n'
}


# Downloads audio in the CWD with best quality, sanitizing the filename + meta.
_dl_audio() {
  local url
  url=${1-}
  if [ -z "$url" ]; then
    printf 'error: missing URL\nusage: %s a URL\n' "${0##*/}" >&2
    exit 64
  fi

  # Best audio.
  # Extract audio
  # Beautiful information is embedded in the file.
  # Beautiful thumbnail is embedded in the file.
  # For potential MKV/MKA
  # make deterministic, ignore user defaults
  # widespread format, while good quality, not webp niche.
  # sanitization of filename
  # Parallel of 4 workers.

"$YT_BIN" \
    --no-playlist \
    -f 'ba/b' \
    -x \
    --embed-metadata \
    --parse-metadata "%(uploader|)s:%(meta_artist)s" \
    --embed-thumbnail \
    --embed-chapters \
    --ignore-config \
    --convert-thumbnails png \
    --restrict-filenames \
    --trim-filenames 128 \
    -N 4 \
    -o '%(title)s.%(ext)s' \
    "${url}"

  # Add these flags for subtitles compatibility (at the cost of an .mka container, less mainstream)
    # --remux-video mka \
    # --write-subs \
    # --embed-subs \
    # --compat-options no-keep-subs \
    # --embed-info-json \

}

# Downloads video in the CWD with best quality, sanitizing the filename + meta.
_dl_video() {
  local url
  url=${1-}
  if [ -z "$url" ]; then
    printf 'error: missing URL\nusage: %s v URL\n' "${0##*/}" >&2
    exit 64
  fi

  "$YT_BIN" \
  --ignore-config \
  --no-playlist \
  -f "bv*+ba/b" \
  --embed-metadata \
  --embed-thumbnail \
  --write-subs \
  --embed-subs \
  --compat-options no-keep-subs \
  --embed-chapters \
  --convert-thumbnails 'png' \
  --embed-info-json \
  --restrict-filenames \
  --trim-filenames 128 \
  --remux-video mkv \
  -N 4 \
  -o '%(title)s.%(ext)s' \
  "$url"

}


_print_bright_green() {
  printf '\033[92m%s\033[0m\n\n' "${1-}"
}

# Parse args
case "${1-}" in
  a|-a|--audio)
    url="${2-}"
    [[ -n $url ]] || _usage_exit
    shift 2
    _print_bright_green '[ AUDIO MODE ]'
    _install_py_deps
    _dl_audio "$url"
    ;;
  v|-v|--video)
    url="${2-}"
    [[ -n $url ]] || _usage_exit
    shift 2
    _print_bright_green '[ VIDEO MODE ]'
    _install_py_deps
    _dl_video "$url"
    ;;
  *)
    # No wrapper flag: behave like plain yt-dlp.
    "$YT_BIN" "$@"
    ;;
esac

