#!/usr/bin/python

import subprocess
import re
import sys

class Sink:
  def __init__(self, num):
    self.num = num
    self.state = None
    self.description = None
    self.volume = None
    self.mute = None

  def __str__(self):
    return 'Sink #{}, {}, {}, volume={}, mute={}'.format(
        self.num, self.description, self.state, self.volume, self.mute)

def pactl_get_all_sinks():
  sinks = []
  active_sink = None
  pactl = subprocess.run(['pactl', 'list', 'sinks'], stdout=subprocess.PIPE)
  output = pactl.stdout.decode('utf-8')
  for line in output.splitlines():

    sink = re.match(r'Sink #([0-9]*)', line)
    if sink:
      num = int(sink.group(1))
      sinks += [Sink(num)]

    description = re.match(r'\s*Description: (.*)', line)
    if description:
      active_sink.description = description.group(1)

    state = re.match(r'\s*State: (.*)', line)
    if state:
      active_sink.state = state.group(1)

    volume = re.match(r'\s*Volume: .*\s([0-9]+)%', line)
    if volume:
      active_sink.volume = volume.group(1)

    mute = re.match(r'\s*Mute: (.*)', line)
    if mute:
      active_sink.mute = mute.group(1)

    if len(sinks) > 0:
      active_sink = sinks[len(sinks) - 1]

  return sinks

def find_active_sink(sinks):
  active_sink = None

  # Check if a sink is in the 'RUNNING' state.
  for sink in sinks:
    if sink.state in ['RUNNING']:
      active_sink = sink

  # Otherwise use a default one (1)
  if not active_sink and len(sinks) > 0:
    active_sink = sinks[len(sinks) - 1]

  return active_sink

if __name__ == '__main__':
  if len(sys.argv) < 2:
    print('Usage: {} up/down/get/toggle'.format(sys.argv[0]))
    sys.exit(1)

  sinks = pactl_get_all_sinks()
  sink = find_active_sink(sinks)
  active = str(sink.num)

  for s in sinks:
    print(s, file=sys.stderr)

  cmd = sys.argv[1]
  if cmd == 'up':
    subprocess.run(['pactl', 'set-sink-mute', active, 'false'])
    subprocess.run(['pactl', 'set-sink-volume', active, '+5%'])
  elif cmd == 'down':
    subprocess.run(['pactl', 'set-sink-mute', active, 'false'])
    subprocess.run(['pactl', 'set-sink-volume', active, '-5%'])
  elif cmd == 'toggle':
    subprocess.run(['pactl', 'set-sink-mute', active, 'toggle'])
  elif cmd == 'get':
    print(sink.volume)
  elif cmd == 'set':
    if len(sys.argv) < 3:
      print('Missing volume parameter')
      sys.exit(1)
    vol = sys.argv[2]
    subprocess.run(['pactl', 'set-sink-volume', active, '{}%'.format(vol)])
