#!/usr/bin/env python3

import subprocess
import json
import sys
import hashlib
import logging
from urllib.parse import urljoin

from lxml import etree

import requests


def error(msg):
  print(msg, file=sys.stderr)
  sys.exit(2)


def get_conf():
  secret, base_url = "", ""
  out = subprocess.check_output(["bbb-conf", "--secret"])
  for line in out.splitlines():
    line = line.strip().decode('utf-8')
    if line.lower().startswith('url:'):
      base_url = line[len('url: '):]
    if line.lower().startswith('secret:'):
      secret = line[len('secret: '):]
  return secret, base_url + 'api/'


def checksum(secret, baseurl, endpoint):
  content = endpoint + secret
  sha1 = hashlib.sha1()
  sha1.update(content.encode('utf-8'))
  return sha1.hexdigest()


def get(baseurl, endpoint, secret):
  url = urljoin(baseurl, endpoint + '?checksum=' + checksum(secret, baseurl, endpoint))
  try:
    res = requests.get(url)
  except Exception:
    logging.exception('fail to make api call')
    return os.exit(2)
  return etree.fromstring(res.text)


def dump_meetings(baseurl, secret):
  t = get(baseurl, 'getMeetings', secret)
  meetings = t.findall('.//meeting')
  metrics = {
   'meetings': len(meetings),
   'inactive_meetings': 0,
   'participants': 0,
   'voice_participants': 0,
   'video_participants': 0,
   'listeners': 0
  }
  for node in meetings:
    participants = int(node.find('participantCount').text)
    voice_participants = int(node.find('voiceParticipantCount').text)
    video_participants = int(node.find('videoCount').text)
    listeners = int(node.find('listenerCount').text)
    metrics['participants'] += participants
    metrics['voice_participants'] += voice_participants
    metrics['video_participants'] += video_participants
    metrics['listeners'] += listeners
    if participants == 0:
      metrics['inactive_meetings'] += 1
  return metrics


def dump_recordings(baseurl, secret):
  t = get(baseurl, 'getRecordings', secret)
  metrics = {'processing_recordings': 0, 'processed_recordings': 0, 'published_recordings': 0, 'unpublished_recordings': 0}
  for node in t.findall('.//recording'):
    origstate = node.find('state').text
    state = origstate + '_recordings'
    if state not in metrics:
      return error('unknown state `%s`' % origstate)
    metrics[state] += 1
  return metrics


def main():
  secret, baseurl = get_conf()
  metrics = {}
  metrics.update(dump_recordings(baseurl, secret))
  metrics.update(dump_meetings(baseurl, secret))
  print(json.dumps(metrics))


main()