#!/usr/bin/env python3
"""cosmic-call-merge - fold baresip's two recording legs into one file per call.

OPTIONAL and OFF by default. Only relevant when you have both:
  * loaded baresip's sndfile module with snd_path pointing at a directory, and
  * set [recording] dir in phone.conf to that same directory.

CALL RECORDING IS REGULATED. Many jurisdictions require the consent of every
party to a call. Check the law that applies to you before enabling it.

baresip's sndfile module writes a separate wav per direction (dump-*.wav).
This pairs the newest two and writes <dir>/YYYY-MM-DD_HHMMSS_<peer>.wav as a
2-channel file (one side per channel). Raw legs are deleted only after ffmpeg
reports success. cosmic-phoned runs this after each call when enabled.
"""
import os
import subprocess
import sys
import time


def _libpath():
    here = os.path.dirname(os.path.realpath(__file__))
    for p in (os.environ.get("COSMIC_PHONE_LIB"), os.path.join(here, "..", "lib"),
              os.path.expanduser("~/.local/lib/cosmic-tools/phone")):
        if p and os.path.isdir(os.path.join(p, "cosmic_phone")):
            return p
    return ""


sys.path.insert(0, _libpath())

from cosmic_phone import config  # noqa: E402

MAX_AGE = 6 * 60 * 60


def legs(rec):
    out = []
    try:
        for n in os.listdir(rec):
            p = os.path.join(rec, n)
            if n.startswith("dump-") and n.endswith(".wav") and time.time() - os.path.getmtime(p) < MAX_AGE:
                out.append(p)
    except OSError:
        return []
    return sorted(out, key=os.path.getmtime)


def merge(rec, files, label):
    stamp = time.strftime("%Y-%m-%d_%H%M%S", time.localtime(os.path.getmtime(files[0])))
    dest = os.path.join(rec, "%s_%s.wav" % (stamp, label) if label else "%s.wav" % stamp)
    cmd = ["ffmpeg", "-nostdin", "-y", "-loglevel", "error"]
    for f in files:
        cmd += ["-i", f]
    if len(files) >= 2:
        cmd += ["-filter_complex", "[0:a][1:a]amerge=inputs=2[a]", "-map", "[a]", "-ac", "2"]
    cmd.append(dest)
    r = subprocess.run(cmd, capture_output=True, text=True, timeout=180)
    if r.returncode != 0 or not os.path.exists(dest):
        print("cosmic-call-merge: ffmpeg failed, keeping raw legs:\n%s" % r.stderr.strip()[:400],
              file=sys.stderr)
        return None
    for f in files:
        try:
            os.unlink(f)
        except OSError:
            pass
    return dest


def main():
    rec = config.expand(config.load().get("recording", "dir").strip())
    if not rec:
        return 0                     # recording disabled
    time.sleep(2)                    # let sndfile close its files
    found = legs(rec)
    if not found:
        return 0
    peer = "".join(c for c in (sys.argv[1] if len(sys.argv) > 1 else "") if c.isdigit())
    out = merge(rec, found[-2:], peer)
    if out:
        print(out)
    return 0


if __name__ == "__main__":
    sys.exit(main())
