#!/usr/bin/env python3
"""SMTP/Mailpit client tool for ScadaBridge test infrastructure."""

import argparse
import email.mime.text
import json
import smtplib
import sys
import urllib.request


DEFAULT_SMTP_HOST = "localhost"
DEFAULT_SMTP_PORT = 1025
DEFAULT_API_URL = "http://localhost:8025/api"


def cmd_check(args):
    """Test SMTP connectivity and report Mailpit status."""
    # Test SMTP connection
    try:
        server = smtplib.SMTP(args.host, args.port, timeout=5)
        server.ehlo()
        smtp_ok = True
        server.quit()
    except Exception as e:
        smtp_ok = False
        smtp_err = str(e)

    # Test API/web UI
    try:
        req = urllib.request.Request(f"{args.api}/v1/info")
        with urllib.request.urlopen(req, timeout=5) as resp:
            info = json.loads(resp.read())
        api_ok = True
    except Exception as e:
        api_ok = False
        api_err = str(e)

    print(f"SMTP ({args.host}:{args.port}): {'OK' if smtp_ok else 'FAILED - ' + smtp_err}")
    print(f"Web UI/API ({args.api}): {'OK' if api_ok else 'FAILED - ' + api_err}")

    if api_ok:
        print(f"\nMailpit version:    {info.get('Version', 'unknown')}")
        print(f"Database path:      {info.get('DatabasePath', 'unknown')}")
        messages = info.get('Messages', 0)
        print(f"Stored messages:    {messages}")

    if smtp_ok and api_ok:
        print("\nSMTP server is healthy.")
    else:
        sys.exit(1)


def cmd_send(args):
    """Send a test email via SMTP."""
    msg = email.mime.text.MIMEText(args.body, "plain")
    msg["Subject"] = args.subject
    msg["From"] = args.sender
    msg["To"] = args.to

    if args.bcc:
        recipients = [args.to] + [b.strip() for b in args.bcc.split(",")]
    else:
        recipients = [args.to]

    try:
        server = smtplib.SMTP(args.host, args.port, timeout=5)
        server.ehlo()
        server.sendmail(args.sender, recipients, msg.as_string())
        server.quit()
        bcc_note = f" (BCC: {args.bcc})" if args.bcc else ""
        print(f"Sent: {args.sender} -> {args.to}{bcc_note}")
        print(f"Subject: {args.subject}")
    except Exception as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)


def cmd_list(args):
    """List messages in Mailpit inbox."""
    try:
        req = urllib.request.Request(f"{args.api}/v1/messages?limit={args.limit}")
        with urllib.request.urlopen(req, timeout=5) as resp:
            data = json.loads(resp.read())
    except Exception as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)

    total = data.get("messages_count", 0)
    messages = data.get("messages", [])

    print(f"Messages: {len(messages)} shown / {total} total\n")

    if not messages:
        print("(inbox empty)")
        return

    print(f"{'ID':<24} {'Date':<22} {'From':<30} {'To':<30} {'Subject'}")
    print("-" * 130)

    for msg in messages:
        msg_id = msg["ID"]
        date = msg.get("Date", "")[:21]
        from_addr = msg.get("From", {}).get("Address", "")[:28]
        to_list = msg.get("To", [])
        to_addr = (to_list[0].get("Address", "") if to_list else "")[:28]
        subject = msg.get("Subject", "")[:40]
        print(f"{msg_id:<24} {date:<22} {from_addr:<30} {to_addr:<30} {subject}")


def cmd_read(args):
    """Read a specific message by ID."""
    try:
        req = urllib.request.Request(f"{args.api}/v1/message/{args.id}")
        with urllib.request.urlopen(req, timeout=5) as resp:
            msg = json.loads(resp.read())
    except Exception as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)

    print(f"ID:      {msg['ID']}")
    print(f"Date:    {msg.get('Date', '')}")
    from_info = msg.get("From", {})
    print(f"From:    {from_info.get('Name', '')} <{from_info.get('Address', '')}>")

    for field in ["To", "Cc", "Bcc"]:
        addrs = msg.get(field, [])
        if addrs:
            formatted = ", ".join(f"{a.get('Name', '')} <{a.get('Address', '')}>" for a in addrs)
            print(f"{field}:      {formatted}")

    print(f"Subject: {msg.get('Subject', '')}")
    print()
    print(msg.get("Text", "(no text body)"))


def cmd_clear(args):
    """Delete all messages in Mailpit."""
    try:
        req = urllib.request.Request(f"{args.api}/v1/messages", method="DELETE")
        with urllib.request.urlopen(req, timeout=5) as resp:
            resp.read()
        print("All messages deleted.")
    except Exception as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)


def main():
    parser = argparse.ArgumentParser(description="SMTP/Mailpit client tool for ScadaBridge test infrastructure")
    parser.add_argument("--host", default=DEFAULT_SMTP_HOST, help=f"SMTP host (default: {DEFAULT_SMTP_HOST})")
    parser.add_argument("--port", type=int, default=DEFAULT_SMTP_PORT, help=f"SMTP port (default: {DEFAULT_SMTP_PORT})")
    parser.add_argument("--api", default=DEFAULT_API_URL, help=f"Mailpit API URL (default: {DEFAULT_API_URL})")

    sub = parser.add_subparsers(dest="command", required=True)

    sub.add_parser("check", help="Test SMTP connectivity and Mailpit status")

    send_p = sub.add_parser("send", help="Send a test email")
    send_p.add_argument("--sender", default="scada-notifications@company.com",
                        help="From address (default: scada-notifications@company.com)")
    send_p.add_argument("--to", required=True, help="Recipient address")
    send_p.add_argument("--bcc", help="Comma-separated BCC addresses")
    send_p.add_argument("--subject", default="Test notification", help="Subject line")
    send_p.add_argument("--body", default="This is a test notification from ZB.MOM.WW.ScadaBridge.", help="Message body")

    list_p = sub.add_parser("list", help="List messages in Mailpit inbox")
    list_p.add_argument("--limit", type=int, default=20, help="Number of messages to show (default: 20)")

    read_p = sub.add_parser("read", help="Read a specific message by ID")
    read_p.add_argument("--id", required=True, help="Message ID (from list command)")

    sub.add_parser("clear", help="Delete all messages")

    args = parser.parse_args()

    commands = {
        "check": cmd_check,
        "send": cmd_send,
        "list": cmd_list,
        "read": cmd_read,
        "clear": cmd_clear,
    }

    commands[args.command](args)


if __name__ == "__main__":
    main()
