#!/usr/bin/bash

# heos-nowplaying  Copyright 2025-2026  Norman Carver

# Script program to print (to stdout) information about the current selection of a HEOS player/group.
# (Selection may or may not actually be playing, use heos-state to check play/stop status.)
#
# A player is specified with:
# (1) a (sub)string of the player's HEOS name, or
# (2) its IP num (i.e., host portion of its dotted quad IP address).
#
# With the -g option, a group is specified:
# (1) a (sub)string of the group's HEOS name, or
# (2) its Group ID (GID).
#
# Sends commands to the default HEOS master device, but can select alternative
# using the MASTER_IPNUM argument option.


function print_usage()
{
    echo -e "Print the Now Playing info (current selection) of a HEOS Player/Group.\n" >&2
    echo    "Usage: heos-nowplaying [-g] PLAYER [MASTER_IPNUM]" >&2
    echo    "where:" >&2
    echo    "  PLAYER is a HEOS Player's Name (substring) or its IPNUM;" >&2
    echo    "  MASTER_IPNUM -- use a non-default HEOS master device;" >&2
    echo -e "  (IPNUM means the last quad of an IP address only: i.e., 0--255.)\n" >&2
    echo    "Options:" >&2
    echo    "  -g -- group: PLAYER is a group Name or GID;" >&2
}


if [[ "$1" == --help ]]; then
    print_usage
    exit 0
fi

# Process supplied options:
pgopt=--player
pidopt=""
debugopt=""
while [[ "$1" == -* ]]; do
    if [[ "$1" == -g ]]; then
        pgopt=--group
    elif [[ "$1" == --pid=?* ]]; then
        pidopt=$1
    elif [[ "$1" == -- ]]; then
        shift;break
    elif [[ "$1" == --debug ]]; then
        debugopt=--debug
    else
        echo "Error: invalid option '$1'" >&2
        echo "(use '--' to signal end of options, with -* arguments)" >&2
        exit 1
    fi
    shift
done

# Process command arguments:
if [[ $# == 0 || $# -gt 2 ]]; then
    print_usage
    exit 1
fi

player=$1
if [[ $# == 2 ]]; then
    master=${2}
else
    master=""
fi
heosdir=$(dirname "$0")


# heosutil-run-command error checking function (one json output):
# args: 1) command result variable; 2) error message; [3) error action]
# (default action on error is 'exit 1', use $3 of 'return 1' to continue execution)
function error_check_run_command()
{
    cmdresult=${!1}
    if [[ ($? != 0) || ("$cmdresult" != *'"result": "success"'*) ]]; then
        if [[ "$cmdresult" == Error:* || ($debugopt == --debug && "$cmdresult" == ERROR:*) ]]; then
            echo "$cmdresult" >&2
        fi
        if [[ -n "$2" ]]; then echo "$2" >&2; fi
        if [[ $# == 3 ]]; then $3; else exit 1; fi
    else
        return 0
    fi
}


# Get the Now Playing info (in JSON format):
playingjson=$("$heosdir"/heosutils/heosutil-run-command ${pgopt}="$player" $pidopt "heos://player/get_now_playing_media?pid=\${pid}" $master)
error_check_run_command playingjson "Error: failed to retrieve Now Playing info from Player/Group ('$player')!"

# Extract Payload info:
payload=$(grep -Eo '"payload": \{[^}]*\}' <<< "$playingjson")
playing=${payload#\"payload\":\ }
if [[ "$playing" == {} ]]; then
    echo "Error: Now Playing info is Empty for Player/Group ('$player')!" >&2
    exit 1
fi

# Reformat and output Now Playing info:
{
  stationp=false
  type=${playing#*\"type\":\ \"}
  type=${type%%\"[,\}]*}
  if [[ "$type" == station ]]; then
      stationp=true
      station=${playing#*\"station\":\ \"}
      station=${station%%\"[,\}]*}
      echo "Station: $station"
  fi

  artist=${playing#*\"artist\":\ \"}
  artist=${artist%%\"[,\}]*}
  if [[ -n "$artist" ]]; then
      echo "Artist:  $artist"
  fi

  song=${playing#*\"song\":\ \"}
  song=${song%%\"[,\}]*}
  if [[ -n "$song" ]]; then
      echo "Song:    $song"
  fi

  album=${playing#*\"album\":\ \"}
  album=${album%%\"[,\}]*}
  if [[ -n "$album" ]]; then
      echo "Album:   $album"
  fi

  if ! $stationp; then
      qid=${playing#*\"qid\":\ }
      qid=${qid%%[,\}]*}
      echo "QID: $qid"
  fi
} <<<"$playing"

#EOF
