"""AFOS Database Workflow."""

import click
from pyiem.wmo import WMOProduct
from twisted.internet import reactor

from pywwa import LOG, common
from pywwa.database import get_database
from pywwa.ldm import bridge
from pywwa.memclient import write_memcache

MEMCACHE_EXCLUDE = [
    "RR1",
    "RR2",
    "RR3",
    "RR4",
    "RR5",
    "RR6",
    "RR7",
    "RR8",
    "RR9",
    "ROB",
    "HML",
]


def write2memcache(product_id: str, text: str):
    """write our TextProduct to memcached"""
    # 10 minutes should be enough time
    LOG.debug("writing %s to memcache", product_id)
    write_memcache(
        product_id.encode("utf-8"),
        text.encode("utf-8"),
        expire=600,
    )


def process_data(txn, buf):
    """Actually do something with the buffer, please"""
    if buf.strip() == "":
        return None
    utcnow = common.utcnow()

    nws = WMOProduct(buf, utcnow=utcnow)

    # When we are in realtime processing, do not consider old data, typically
    # when a WFO fails to update the date in their MND
    if not common.replace_enabled():
        delta = (nws.valid - utcnow).total_seconds()
        if delta < (-180 * 86400):  # 180 days
            raise ValueError(f"Very Latent Product! {nws.valid}")
        if delta > (6 * 3600):  # Six Hours
            raise ValueError(f"Product from the future! {nws.valid}")
    if nws.warnings:
        common.email_error("\n".join(nws.warnings), buf)
    if nws.afos is None:
        if nws.source[0] not in ["K", "P"]:
            return None
        raise ValueError("TextProduct.afos is null")

    if common.replace_enabled():
        txn.execute(
            "DELETE from products where pil = %s and source = %s and "
            "entered = %s and bbb is not distinct from %s",
            (
                nws.afos,
                nws.source,
                nws.valid,
                nws.bbb,
            ),
        )
        LOG.info("Removed %s rows for %s", txn.rowcount, nws.get_product_id())

    txn.execute(
        "INSERT into products (pil, data, entered, "
        "source, wmo, bbb) VALUES(%s, %s, %s, %s, %s, %s)",
        (
            nws.afos.strip(),
            nws.unixtext,
            nws.valid,
            nws.source,
            nws.wmo,
            nws.bbb,
        ),
    )
    if nws.afos[:3] in MEMCACHE_EXCLUDE:
        return None
    # We are on a thread, so we need to send this back to the main thread
    reactor.callFromThread(write2memcache, nws.get_product_id(), nws.unixtext)
    return nws


@click.command(help=__doc__)
@common.init
@common.disable_xmpp
def main(*args, **kwargs):
    """Fire up our workflow."""
    bridge(process_data, dbpool=get_database("afos", cp_max=5))
