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

"""Local gathering.

Usage: %prog [-d] [-i] class ...
or:    %prog [-h|-c|-e|-l]

Arguments:
  class            -- gathering class (e.g. md5, ps, passwd, group)
"""

import os
import sys
import time
import logging
from optparse import OptionParser

if __name__ == "__main__":
    from sigma.util.utf8 import ensure_utf8_mode
    ensure_utf8_mode()
    from sigma.util.winquiet import suppress_child_windows
    suppress_child_windows()

from sigma.util import avalog
from sigma.util import config
from sigma.util.errors import usage, error
from sigma.gather import gathering

parser = OptionParser(usage=__doc__.strip())
parser.add_option("-d", "--debug", action="store_true", dest="debug",
                  help="produce debug output to stdout")
parser.add_option("-i", "--incremental",
                  help="send incremental gathering data to central server",
                  action="store_true", dest="incremental")
parser.add_option("-c", "--clear", dest="clear", action="store_true",
                  help="clear the gather directory, no questions asked (!!!)")
parser.add_option("-e", "--expire", dest="expire", action="store_true",
                  help="expire older files from gather directory")
parser.add_option("-l", "--listing", dest="listing", action="store_true",
                  help="list contents of gather directory")

logger = logging.getLogger("gather")

def main(args=None):
    """Main program.

    This may be invoked with a list of command line options and arguments;
    by default sys.argv[1:] is used.
    """

    options = config.Options()
    avalog.setupLogging(options)
    g = gathering.Gatherer(options)

    opts, args = parser.parse_args(args)
    if opts.clear or opts.expire or opts.listing:
        if args:
            return usage("-c/--clear, -e/--erase and -l/--listing "
                         "don't allow class arguments")
        if opts.expire:
            g.periodic_cleanup()
        if opts.clear:
            g.full_clear()
        if opts.listing:
            print_listing(g, options)
        return 0

    if not args:
        return usage("At least one class argument is required")

    gathering.global_debug = opts.debug
    if opts.incremental:
        method = g.incr_gather
    else:
        method = g.full_gather
    sts = 0
    for cls in args:
        if not g.check_gatherer(cls):
            logger.error("No gatherer %r", cls)
            sts = 1
        else:
            method(cls)
    return sts

def print_listing(g, options):
    dirname = gathering.get_gather_dir(options)
    if not os.path.isdir(dirname):
        print("Gather directory %r doesn't exist" % dirname)
        return
    names = os.listdir(dirname)
    if not names:
        print("Nothing gathered in %r" % dirname)
        return
    names.sort()
    print("Contents of %r" % dirname)
    print("%-15s %-7s  %s" % ("CLASS", "VERSION", "LAST GATHERED"))
    for name in names:
        if name.endswith(".tmp"):
            continue
        filename = os.path.join(dirname, name)
        i = name.find(".")
        cls = name[:i]
        version = name[i+1:]
        mtime = os.path.getmtime(filename)
        print("%-15s %-7s  %s" % (cls, version, time.ctime(mtime)))

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