#!/usr/bin/python3
# vim: shiftwidth=4 tabstop=4 expandtab

import argparse
import json
import logging
import os
import subprocess  # nosec B404
import sys

import dotenv

# Load ee-postfix-tools configurations in environment
config_dir = "/etc/ee-postfix-tools"
if os.path.isdir(config_dir):
    for file in sorted([f for f in os.listdir(config_dir) if f.endswith(".conf")]):
        dotenv.load_dotenv(os.path.join(config_dir, file), override=True)

parser = argparse.ArgumentParser()
parser.add_argument("-d", "--debug", action="store_true")
parser.add_argument("-v", "--verbose", action="store_true")
parser.add_argument(
    "-i",
    "--instance",
    help="Select postfix instance (optional, default: use default postfix instance)",
    default=os.environ.get("POSTFIX_INSTANCE"),
)
parser.add_argument(
    "-J",
    "--json",
    action="store_true",
    help="JSON output",
)
parser.add_argument(
    "count",
    type=int,
    nargs="?",
    default=10,
    help="Senders count to display (default: 10, use zero to display all senders)",
)
args = parser.parse_args()

if args.debug:
    loglevel = logging.DEBUG
elif args.verbose:
    loglevel = logging.INFO
else:
    loglevel = logging.WARNING

logging.basicConfig(
    level=loglevel,
    format="%(asctime)s - %(levelname)s - %(message)s",
    datefmt="%m/%d/%Y %I:%M:%S %p",
)

cmd = ["/usr/sbin/postqueue", "-j"]
if args.instance:
    cmd = ["/usr/sbin/postmulti", "-i", args.instance, "-x"] + cmd
logging.debug("Run '%s'", "' '".join(cmd))

proc = subprocess.run(cmd, shell=False, stdout=subprocess.PIPE)  # nosec B603
output = proc.stdout.decode()

senders = {}
current_sender = None
for line in output.split("\n"):
    # Ignore empty line
    if not line:
        continue
    try:
        msg = json.loads(line)
    except ValueError:
        logging.warning("Fail to decode JSON message line: '%s'", line)
        continue

    if msg["sender"] not in senders:
        senders[msg["sender"]] = 0
    senders[msg["sender"]] += len(msg["recipients"])


top_senders = sorted(senders.keys(), key=lambda sender: senders[sender], reverse=True)
if args.count:
    top_senders = top_senders[: args.count]

if args.json:
    json.dump({sender: senders[sender] for sender in top_senders}, sys.stdout)
else:
    for sender in top_senders:
        print(f"{senders[sender]}\t{sender}")
