#!/usr/bin/python3
"""Serve diagnostics of the router's first setup on PORT, with the Python standard library alone.

Run by vpn-router-bootstrap.service, which vpn-router-setup starts until a setup has succeeded and
then stops. Every request on any address answers, as plain text, the output of COMMANDS run at that
moment: the state of the last setup run, the state of the services, the addresses, and the end of
the logs.
"""

import subprocess
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer

PORT = 17081

#: The title of each section and its command.
COMMANDS = (
    ('Setup state', ['cat', '/run/vpn-router/setup.json']),
    ('Services', ['systemctl', 'is-active', 'vpn-router-setup', 'vpn-router-web', 'slapd', 'postgresql',
                  'strongswan', 'openvpn-server@vpn-router', 'wg-quick@wg0']),
    ('Failed units', ['systemctl', '--failed', '--no-legend', '--plain']),
    ('Addresses', ['ip', '-brief', 'address']),
    ('Routes', ['ip', 'route']),
    ('cloud-init', ['cloud-init', 'status', '--long']),
    ('vpn-router-setup log', ['journalctl', '--unit', 'vpn-router-setup', '--lines', '60', '--no-pager', '--output', 'short-iso']),
    ('vpn-router-web log', ['journalctl', '--unit', 'vpn-router-web', '--lines', '30', '--no-pager', '--output', 'short-iso']),
)


def report():
    """The output of every command of COMMANDS under its title."""
    sections = []
    for title, command in COMMANDS:
        try:
            result = subprocess.run(command, capture_output=True, text=True, timeout=10)
            text = (result.stdout + result.stderr).rstrip()
        except (OSError, subprocess.TimeoutExpired) as exc:
            text = f'cannot run {command[0]}: {exc}'
        sections.append(f'== {title} ==\n{text}\n')
    return '\n'.join(sections)


class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        body = report().encode()
        self.send_response(200)
        self.send_header('Content-Type', 'text/plain; charset=utf-8')
        self.send_header('Content-Length', str(len(body)))
        self.send_header('Cache-Control', 'no-store')
        self.send_header('Refresh', '10')
        self.end_headers()
        self.wfile.write(body)


if __name__ == '__main__':
    ThreadingHTTPServer(('', PORT), Handler).serve_forever()
