# API key for The Movie Database (TMDB)
tmdb_api_key: ""

# Client ID for SIMKL API (optional, improves metadata matching)
# Get your free client ID at: https://simkl.com/settings/developer/
simkl_client_id: ""

# Group or Username to postfix to the end of all download filenames following a dash
tag: user_tag

# Enable/disable tagging with group name (default: true)
tag_group_name: true

# Enable/disable tagging with IMDB/TMDB/TVDB details (default: true)
tag_imdb_tmdb: true

# Set terminal background color (custom option not in CONFIG.md)
set_terminal_bg: false

# Set file naming convention
#  true for style - Prime.Suspect.S07E01.The.Final.Act.Part.One.1080p.ITV.WEB-DL.AAC2.0.H.264
#  false for style - Prime Suspect S07E01 The Final Act - Part One
scene_naming: true

# Whether to include the year in series names for episodes and folders (default: true)
#  true for style - Show Name (2023) S01E01 Episode Name
#  false for style - Show Name S01E01 Episode Name
series_year: true

# Check for updates from GitHub repository on startup (default: true)
update_checks: true

# How often to check for updates, in hours (default: 24)
update_check_interval: 24

# Title caching configuration
# Cache title metadata to reduce redundant API calls
title_cache_enabled: true # Enable/disable title caching globally (default: true)
title_cache_time: 1800 # Cache duration in seconds (default: 1800 = 30 minutes)
title_cache_max_retention: 86400 # Maximum cache retention for fallback when API fails (default: 86400 = 24 hours)

# Debug logging configuration
# Comprehensive JSON-based debug logging for troubleshooting and service development
debug:
  false # Enable structured JSON debug logging (default: false)
  # When enabled with --debug flag or set to true:
  # - Creates JSON Lines (.jsonl) log files with complete debugging context
  # - Logs: session info, CLI params, service config, CDM details, authentication,
  #   titles, tracks metadata, DRM operations, vault queries, errors with stack traces
  # - File location: logs/unshackle_debug_{service}_{timestamp}.jsonl
  # - Also creates text log: logs/unshackle_root_{timestamp}.log

debug_keys:
  false # Log decryption keys in debug logs (default: false)
  # Set to true to include actual decryption keys in logs
  # Useful for debugging key retrieval and decryption issues
  # SECURITY NOTE: Passwords, tokens, cookies, and session tokens
  # are ALWAYS redacted regardless of this setting
  # Only affects: content_key, key fields (the actual CEKs)
  # Never affects: kid, keys_count, key_id (metadata is always logged)

# Muxing configuration
muxing:
  set_title: false

# Login credentials for each Service
credentials:
  # Direct credentials (no profile support)
  EXAMPLE: email@example.com:password

  # Per-profile credentials with default fallback
  SERVICE_NAME:
    default: default@email.com:password # Used when no -p/--profile is specified
    profile1: user1@email.com:password1
    profile2: user2@email.com:password2

  # Per-profile credentials without default (requires -p/--profile)
  SERVICE_NAME2:
    john: john@example.com:johnspassword
    jane: jane@example.com:janespassword

  # You can also use list format for passwords with special characters
  SERVICE_NAME3:
    default: ["user@email.com", ":PasswordWith:Colons"]

# Override default directories used across unshackle
directories:
  cache: Cache
  cookies: Cookies
  dcsl: DCSL # Device Certificate Status List
  downloads: Downloads
  logs: Logs
  temp: Temp
  wvds: WVDs
  prds: PRDs
  # Additional directories that can be configured:
  # commands: Commands
  services:
    - /path/to/services
    - /other/path/to/services
  # vaults: Vaults
  # fonts: Fonts

# Pre-define which Widevine or PlayReady device to use for each Service
cdm:
  # Global default CDM device (fallback for all services/profiles)
  default: WVD_1

  # Direct service-specific CDM
  DIFFERENT_EXAMPLE: PRD_1

  # Per-profile CDM configuration
  EXAMPLE:
    john_sd: chromecdm_903_l3 # Profile 'john_sd' uses Chrome CDM L3
    jane_uhd: nexus_5_l1 # Profile 'jane_uhd' uses Nexus 5 L1
    default: generic_android_l3 # Default CDM for this service

  # NEW: Quality-based CDM selection
  # Use different CDMs based on video resolution
  # Supports operators: >=, >, <=, <, or exact match
  EXAMPLE_QUALITY:
    "<=1080": generic_android_l3 # Use L3 for 1080p and below
    ">1080": nexus_5_l1 # Use L1 for above 1080p (1440p, 2160p)
    default: generic_android_l3 # Optional: fallback if no quality match

  # You can mix profiles and quality thresholds in the same service
  NETFLIX:
    # Profile-based selection (existing functionality)
    john: netflix_l3_profile
    jane: netflix_l1_profile
    # Quality-based selection (new functionality)
    "<=720": netflix_mobile_l3
    "1080": netflix_standard_l3
    ">=1440": netflix_premium_l1
    # Fallback
    default: netflix_standard_l3

# Use pywidevine Serve-compliant Remote CDMs

# Example: Custom CDM API Configuration
# This demonstrates the highly configurable custom_api type that can adapt to any CDM API format
# - name: "chrome"
#   type: "custom_api"
#   host: "http://remotecdm.test/"
#   timeout: 30
#   device:
#     name: "ChromeCDM"
#     type: "CHROME"
#     system_id: 34312
#     security_level: 3
#   auth:
#     type: "header"
#     header_name: "x-api-key"
#     key: "YOUR_API_KEY_HERE"
#     custom_headers:
#       User-Agent: "Unshackle/2.0.0"
#   endpoints:
#     get_request:
#       path: "/get-challenge"
#       method: "POST"
#       timeout: 30
#     decrypt_response:
#       path: "/get-keys"
#       method: "POST"
#       timeout: 30
#   request_mapping:
#     get_request:
#       param_names:
#         scheme: "device"
#         init_data: "init_data"
#       static_params:
#         scheme: "Widevine"
#     decrypt_response:
#       param_names:
#         scheme: "device"
#         license_request: "license_request"
#         license_response: "license_response"
#       static_params:
#         scheme: "Widevine"
#   response_mapping:
#     get_request:
#       fields:
#         challenge: "challenge"
#         session_id: "session_id"
#         message: "message"
#         message_type: "message_type"
#       response_types:
#         - condition: "message_type == 'license-request'"
#           type: "license_request"
#       success_conditions:
#         - "message == 'success'"
#     decrypt_response:
#       fields:
#         keys: "keys"
#         message: "message"
#       key_fields:
#         kid: "kid"
#         key: "key"
#         type: "type"
#       success_conditions:
#         - "message == 'success'"
#   caching:
#     enabled: true
#     use_vaults: true
#     check_cached_first: true

remote_cdm:
  - name: "chrome"
    device_name: chrome
    device_type: CHROME
    system_id: 27175
    security_level: 3
    host: https://domain.com/api
    secret: secret_key
  - name: "chrome-2"
    device_name: chrome
    device_type: CHROME
    system_id: 26830
    security_level: 3
    host: https://domain-2.com/api
    secret: secret_key

  - name: "decrypt_labs_chrome"
    type: "decrypt_labs" # Required to identify as DecryptLabs CDM
    device_name: "ChromeCDM" # Scheme identifier - must match exactly
    device_type: CHROME
    system_id: 4464 # Doesn't matter
    security_level: 3
    host: "https://keyxtractor.decryptlabs.com"
    secret: "your_decrypt_labs_api_key_here" # Replace with your API key
  - name: "decrypt_labs_l1"
    type: "decrypt_labs"
    device_name: "L1" # Scheme identifier - must match exactly
    device_type: ANDROID
    system_id: 4464
    security_level: 1
    host: "https://keyxtractor.decryptlabs.com"
    secret: "your_decrypt_labs_api_key_here"

  - name: "decrypt_labs_l2"
    type: "decrypt_labs"
    device_name: "L2" # Scheme identifier - must match exactly
    device_type: ANDROID
    system_id: 4464
    security_level: 2
    host: "https://keyxtractor.decryptlabs.com"
    secret: "your_decrypt_labs_api_key_here"

  - name: "decrypt_labs_playready_sl2"
    type: "decrypt_labs"
    device_name: "SL2" # Scheme identifier - must match exactly
    device_type: PLAYREADY
    system_id: 0
    security_level: 2000
    host: "https://keyxtractor.decryptlabs.com"
    secret: "your_decrypt_labs_api_key_here"

  - name: "decrypt_labs_playready_sl3"
    type: "decrypt_labs"
    device_name: "SL3" # Scheme identifier - must match exactly
    device_type: PLAYREADY
    system_id: 0
    security_level: 3000
    host: "https://keyxtractor.decryptlabs.com"
    secret: "your_decrypt_labs_api_key_here"

# Key Vaults store your obtained Content Encryption Keys (CEKs)
# Use 'no_push: true' to prevent a vault from receiving pushed keys
# while still allowing it to provide keys when requested
key_vaults:
  - type: SQLite
    name: Local
    path: key_store.db
  # Additional vault types:
  # - type: API
  #   name: "Remote Vault"
  #   uri: "https://key-vault.example.com"
  #   token: "secret_token"
  #   no_push: true  # This vault will only provide keys, not receive them
  # - type: MySQL
  #   name: "MySQL Vault"
  #   host: "127.0.0.1"
  #   port: 3306
  #   database: vault
  #   username: user
  #   password: pass
  #   no_push: false  # Default behavior - vault both provides and receives keys

# Choose what software to use to download data
downloader: aria2c
# Options: requests | aria2c | curl_impersonate | n_m3u8dl_re
# Can also be a mapping:
# downloader:
#   NF: requests
#   AMZN: n_m3u8dl_re
#   DSNP: n_m3u8dl_re
#   default: requests

# aria2c downloader configuration
aria2c:
  max_concurrent_downloads: 4
  max_connection_per_server: 3
  split: 5
  file_allocation: falloc # none | prealloc | falloc | trunc

# N_m3u8DL-RE downloader configuration
n_m3u8dl_re:
  thread_count: 16
  ad_keyword: "advertisement"
  use_proxy: true

# curl_impersonate downloader configuration
curl_impersonate:
  browser: chrome120

# Pre-define default options and switches of the dl command
dl:
  sub_format: srt
  downloads: 4
  workers: 16
  lang:
    - en
    - fr
  EXAMPLE:
    bitrate: CBR

# Chapter Name to use when exporting a Chapter without a Name
chapter_fallback_name: "Chapter {j:02}"

# Case-Insensitive dictionary of headers for all Services
headers:
  Accept-Language: "en-US,en;q=0.8"
  User-Agent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"

# Override default filenames used across unshackle
filenames:
  debug_log: "unshackle_debug_{service}_{time}.jsonl" # JSON Lines debug log file
  config: "config.yaml"
  root_config: "envied.yaml"
  chapters: "Chapters_{title}_{random}.txt"
  subtitle: "Subtitle_{id}_{language}.srt"

# conversion_method:
# - auto (default): Smart routing - subby for WebVTT/SAMI, pycaption for others
# - subby: Always use subby with advanced processing
# - pycaption: Use only pycaption library (no SubtitleEdit, no subby)
# - subtitleedit: Prefer SubtitleEdit when available, fall back to pycaption
# - pysubs2: Use pysubs2 library (supports SRT/SSA/ASS/WebVTT/TTML/SAMI/MicroDVD/MPL2/TMP)
subtitle:
  conversion_method: auto
  # sdh_method: Method to use for SDH (hearing impaired) stripping
  # - auto (default): Try subby (SRT only), then SubtitleEdit (if available), then subtitle-filter
  # - subby: Use subby library (SRT only)
  # - subtitleedit: Use SubtitleEdit tool (Windows only, falls back to subtitle-filter)
  # - filter-subs: Use subtitle-filter library directly
  sdh_method: auto
  # strip_sdh: Automatically create stripped (non-SDH) versions of SDH subtitles
  # Set to false to disable automatic SDH stripping entirely (default: true)
  strip_sdh: true
  # convert_before_strip: Auto-convert VTT/other formats to SRT before using subtitle-filter
  # This ensures compatibility when subtitle-filter is used as fallback (default: true)
  convert_before_strip: true
  # preserve_formatting: Preserve original subtitle formatting (tags, positioning, styling)
  # When true, skips pycaption processing for WebVTT files to keep tags like <i>, <b>, positioning intact
  # Combined with no sub_format setting, ensures subtitles remain in their original format (default: true)
  preserve_formatting: true

# Configuration for pywidevine's serve functionality
serve:
  api_secret: "your-secret-key-here"
  users:
    secret_key_for_user:
      devices:
        - generic_nexus_4464_l3
      username: user
  # devices:
  #   - '/path/to/device.wvd'

# Configuration data for each Service
services:
  # Service-specific configuration goes here
  # Profile-specific configurations can be nested under service names

  # You can override ANY global configuration option on a per-service basis
  # This allows fine-tuned control for services with special requirements
  # Supported overrides: dl, aria2c, n_m3u8dl_re, curl_impersonate, subtitle, muxing, headers, etc.

  # Example: Comprehensive service configuration showing all features
  EXAMPLE:
    # Standard service config
    api_key: "service_api_key"

    # Service certificate for Widevine L1/L2 (base64 encoded)
    # This certificate is automatically used when L1/L2 schemes are selected
    # Services obtain this from their DRM provider or license server
    certificate: |
      CAUSwwUKvQIIAxIQ5US6QAvBDzfTtjb4tU/7QxiH8c+TBSKOAjCCAQoCggEBAObzvlu2hZRsapAPx4Aa4GUZj4/GjxgXUtBH4THSkM40x63wQeyVxlEEo
      # ... (full base64 certificate here)

    # Profile-specific device configurations
    profiles:
      john_sd:
        device:
          app_name: "AIV"
          device_model: "SHIELD Android TV"
      jane_uhd:
        device:
          app_name: "AIV"
          device_model: "Fire TV Stick 4K"

    # NEW: Configuration overrides (can be combined with profiles and certificates)
    # Override dl command defaults for this service
    dl:
      downloads: 4 # Limit concurrent track downloads (global default: 6)
      workers: 8 # Reduce workers per track (global default: 16)
      lang: ["en", "es-419"] # Different language priority for this service
      sub_format: srt # Force SRT subtitle format

    # Override n_m3u8dl_re downloader settings
    n_m3u8dl_re:
      thread_count: 8 # Lower thread count for rate-limited service (global default: 16)
      use_proxy: true # Force proxy usage for this service
      retry_count: 10 # More retries for unstable connections
      ad_keyword: "advertisement" # Service-specific ad filtering

    # Override aria2c downloader settings
    aria2c:
      max_concurrent_downloads: 2 # Limit concurrent downloads (global default: 4)
      max_connection_per_server: 1 # Single connection per server
      split: 3 # Fewer splits (global default: 5)
      file_allocation: none # Faster allocation for this service

    # Override subtitle processing for this service
    subtitle:
      conversion_method: pycaption # Use specific subtitle converter
      sdh_method: auto

    # Service-specific headers
    headers:
      User-Agent: "Service-specific user agent string"
      Accept-Language: "en-US,en;q=0.9"

    # Override muxing options
    muxing:
      set_title: true

  # Example: Service with different regions per profile
  SERVICE_NAME:
    profiles:
      us_account:
        region: "US"
        api_endpoint: "https://api.us.service.com"
      uk_account:
        region: "GB"
        api_endpoint: "https://api.uk.service.com"

  # Example: Rate-limited service
  RATE_LIMITED_SERVICE:
    dl:
      downloads: 2 # Limit concurrent downloads
      workers: 4 # Reduce workers to avoid rate limits
    n_m3u8dl_re:
      thread_count: 4 # Very low thread count
      retry_count: 20 # More retries for flaky service
    aria2c:
      max_concurrent_downloads: 1 # Download tracks one at a time
      max_connection_per_server: 1 # Single connection only

  # Notes on service-specific overrides:
  # - Overrides are merged with global config, not replaced
  # - Only specified keys are overridden, others use global defaults
  # - Reserved keys (profiles, api_key, certificate, etc.) are NOT treated as overrides
  # - Any dict-type config option can be overridden (dl, aria2c, n_m3u8dl_re, subtitle, etc.)
  # - CLI arguments always take priority over service-specific config

# External proxy provider services
proxy_providers:
  nordvpn:
    username: username_from_service_credentials
    password: password_from_service_credentials
    server_map:
      us: 12 # force US server #12 for US proxies
  surfsharkvpn:
    username: your_surfshark_service_username # Service credentials from https://my.surfshark.com/vpn/manual-setup/main/openvpn
    password: your_surfshark_service_password # Service credentials (not your login password)
    server_map:
      us: 3844 # force US server #3844 for US proxies
      gb: 2697 # force GB server #2697 for GB proxies
      au: 4621 # force AU server #4621 for AU proxies
  windscribevpn:
    username: your_windscribe_username # Service credentials from https://windscribe.com/getconfig/openvpn
    password: your_windscribe_password # Service credentials (not your login password)
    server_map:
      us: "us-central-096.totallyacdn.com" # force US server
      gb: "uk-london-055.totallyacdn.com" # force GB server
  basic:
    GB:
      - "socks5://username:password@bhx.socks.ipvanish.com:1080" # 1 (Birmingham)
      - "socks5://username:password@gla.socks.ipvanish.com:1080" # 2 (Glasgow)
    AU:
      - "socks5://username:password@syd.socks.ipvanish.com:1080" # 1 (Sydney)
      - "https://username:password@au-syd.prod.surfshark.com" # 2 (Sydney)
      - "https://username:password@au-bne.prod.surfshark.com" # 3 (Brisbane)
    BG: "https://username:password@bg-sof.prod.surfshark.com"
