#!/usr/bin/env python3
# Copyright 2026 SigmaSRC, Inc. All Rights Reserved.

"""Rudimentary spool queue management tool.

Usage: %prog [-h] [-e] [-l LIMIT] [-c] [-d] [-v]
or:    %prog file ...

Invoke without options or arguments to get a spool queue listing.
Invoke with one or more file names to copy those to the spool queue.

"""

import os
import sys
import shutil
import logging
import optparse

from sigma.util import avalog
from sigma.util.errors import usage, error
from sigma.spool import spooling, qmgr

kbyte = 1024

parser = optparse.OptionParser(usage=__doc__.strip())
parser.add_option("-c", "--clear", dest="clear", action="store_true",
                  help="clear the entire queue, no questions asked (!!!)")
parser.add_option("-d", "--duplicate-removal", dest="dups",
                  action="store_true",
                  help="remove duplicate queue items")
parser.add_option("-e", "--expire", dest="expire", action="store_true",
                  help="expire old queue items")
parser.add_option("-l", "--limit", dest="limit", action="store", type="int",
                  help="expire old items until queue size <= LIMIT Kbytes")
parser.add_option("-v", "--verbose", dest="verbose", action="store_true",
                  help="verbose output when showing queue contents")

def main(args=None):
    opts, args = parser.parse_args(args)
    anyopts = (opts.expire or opts.limit or opts.clear or opts.dups)
    if anyopts and args:
        return usage("Please don't combine file arguments with -e, -l or -c")
    avalog.setupLogging()
    qm = qmgr.QueueManager()
    if anyopts:
        # These operations chat on the log file
        if opts.dups:
            qm.consolidate_duplicates()
        if opts.expire:
            qm.periodic_cleanup()
        if opts.limit > 0:
            qm.limit_quota(opts.limit)
        if opts.clear:
            qm.full_clear()
        return 0
    elif not args:
        any = 0
        totalsize = 0
        for qi in qm.list_items():
            if not any:
                print("Spool queue %s:" % qm.spooldir)
            any += 1
            kbd = (os.path.getsize(qi.filename)+kbyte-1)//kbyte
            kbm = (os.path.getsize(qi.metadatafilename)+kbyte-1)//kbyte
            totalsize += kbd + kbm
            if opts.verbose:
                print("%s (%d+%d KB)" % (qi.filename, kbd, kbm))
                keys = sorted(qi.metadata.keys())

                for key in keys:
                    print("    %-15s : %r" % (key, qi.metadata[key]))
            else:
                datatype = qi.metadata.get("type", "?")
                if datatype == "compliance":
                    datatype += "." + qi.metadata.get("deployment_id", "")
                print("%s (%d+%d KB, %s)" % (os.path.basename(qi.filename),
                                             kbd, kbm, datatype))
        if not any:
            print("Spool queue %s is empty." % qm.spooldir)
        else:
            print("Total spool queue size %d KB for %d items." % (totalsize,
                                                                  any))
        return 0
    else:
        sts = 0
        logger = logging.getLogger("spool")
        # XXX Should errors below be logged too?
        for filename in args:
            base, suffix = os.path.splitext(filename)
            try:
                qitem = qm.new(suffix)
            except ValueError as msg:
                error("Can't create queue item for %r: %s", filename, msg)
                sts = 1
                continue
            try:
                shutil.copyfile(filename, qitem.filename)
            except IOError as msg:
                error("IOError spooling %r: %s", filename, msg)
                qitem.discard()
                sts = 1
            else:
                qitem.spool(type=os.path.basename(filename))
                logger.info("Spooled %r", filename)
        return sts

if __name__ == "__main__":
    sys.exit(main())
