#!/usr/bin/env python3
"""Send one letter; platform splitting and event acknowledgements stay here."""

import json
import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).parent))
from common import RelayClient, message_id, read, settings
from brr.channels.telegram import split_message
from brr.loom.runtime.port import parse_frontmatter


def deliver(path, state, client):
    letter = parse_frontmatter(path.read_text())
    platform, _, chat = letter['to'].partition(':')
    if platform == 'loom' and chat:
        # brnrd.dev reads the answer from the loom's snapshot; nothing to send.
        print(json.dumps(dict(ids=[])))
        return 0
    if platform not in {'telegram', 'whatsapp', 'github'} or not chat:
        print('relay: unknown platform or chat', file=sys.stderr)
        return 3
    if letter.get('edit'):
        print('relay: editing is not supported', file=sys.stderr)
        return 3
    text = letter['body']
    limit = {'telegram': 4000, 'whatsapp': 4096, 'github': 65536}[platform]
    parts = split_message(text, limit=limit, max_chunks=None)
    mapping = read(state / 'messages.json', {})
    event_id = mapping.get(letter.get('re'))
    if platform == 'github' and (not event_id or len(parts) > 1):
        print('relay: github is answered with gh', file=sys.stderr)
        return 3
    ids = []
    for index, part in enumerate(parts):
        payload = dict(body_markdown=part)
        if index == 0 and event_id:
            payload['event_id'] = event_id
        else:
            payload.update(platform=platform, chat_id=chat)
        try:
            result = client.send(payload) or {}
        except RuntimeError as exc:
            # The server refused before sending (unknown chat, closed
            # WhatsApp window, no sender): not sent, but only for the first
            # part. A refusal after a part went out is a partial send.
            if index == 0 and getattr(exc, 'status_code', None) in (404, 409, 501):
                print(f'relay: {exc}', file=sys.stderr)
                return 3
            raise
        if result.get('message_id') not in (None, ''):
            ids.append(message_id(platform, chat, result['message_id']))
    print(json.dumps(dict(ids=ids)))
    return 0


if __name__ == '__main__':
    config, state = settings()
    sys.exit(deliver(Path(sys.argv[1]), state, RelayClient(config.relay_state)))
