#!/usr/bin/python3
#
# Univention Reports
#  Creates reports from LaTeX templates
#
# SPDX-FileCopyrightText: 2007-2025 Univention GmbH
# SPDX-License-Identifier: AGPL-3.0-only


import locale
import os.path
import shutil
import sys
from optparse import OptionParser

import univention.admin.uldap
import univention.debug as ud
from univention.config_registry import ConfigRegistry
from univention.lib.i18n import Translation


translation = Translation('univention-directory-reports')
_ = translation.translate

ucr = ConfigRegistry()
ucr.load()


def dump_modules(cfg, module=None, out=sys.stdout):
    """Dump reports for specific or all known modules."""
    modules = cfg._reports.keys() if module is None else [module]
    for module in modules:
        print('Reports for module: %s' % module, file=out)
        for name in cfg.get_report_names(module):
            print(' - %s' % name, file=out)


def main():
    # important! set locale before importing
    locale.setlocale(locale.LC_ALL, "")
    translation.set_language()
    from univention.directory.reports import Config, Report, ReportError

    cfg = Config()

    parser = OptionParser(usage='usage: %prog -m <module> [options] dn1 dn2 ...')
    parser.add_option(
        '-u', '--user', action='store',
        dest='user', default=None, metavar='USERDN',
        help='User-DN for simple LDAP access')
    parser.add_option(
        '-p', '--password', action='store',
        dest='password', default=None,
        help='Password for simple LDAP access')
    parser.add_option(
        '-H', '--header', action='store',
        dest='header', default=None,
        help='File containing the header for the report')
    parser.add_option(
        '-F', '--footer', action='store',
        dest='footer', default=None,
        help='file containing the footer for the report')
    parser.add_option(
        '-s', '--server', action='store',
        dest='server', default=ucr.get('ldap/server/name', 'localhost'),
        help='LDAP server [%default]')
    parser.add_option(
        '-b', '--base', action='store',
        dest='base', default=ucr.get('ldap/base', ''),
        help='LDAP base [%default]')
    parser.add_option(
        '-m', '--module', action='store',
        dest='module', default=None,
        help='admin module defining the report to generate')
    parser.add_option(
        '-r', '--report', action='store',
        dest='report', default=cfg.default_report_name,
        help='Name of the report to use [%default]')
    parser.add_option(
        '-l', '--list', action='store_true',
        dest='list_reports', default=False,
        help='List names of available reports')
    parser.add_option(
        '-c', '--config', action='store',
        dest='config', default='/etc/univention/directory/reports/config.ini',
        help='location of the configuration file [%default]')
    parser.add_option(
        '-d', '--debug', action='store', type='int',
        dest='debug', default=0,
        help='if given than debugging is activated and set to the specified level')
    parser.add_option(
        '--output-dir', action='store',
        help='location of the output report file')
    parser.add_option(
        '--output-name', action='store',
        help='custom output report file name')

    (options, args) = parser.parse_args()

    ud.init('/var/log/univention/directory-reports.log', ud.FLUSH, ud.FUNCTION)
    ud.set_level(ud.ADMIN, options.debug)

    cfg = Config(options.config)

    if options.list_reports:
        dump_modules(cfg, options.module)
        sys.exit(0)

    if not args:
        parser.print_usage(sys.stderr)
        print(_("Error: no DNs specified on command line"), file=sys.stderr)
        sys.exit(2)

    if options.output_name and options.output_name != os.path.basename(options.output_name):
        parser.print_usage(sys.stderr)
        print(_("Error: invalid output_name not allowed characters ['/'] "), file=sys.stderr)
        sys.exit(2)

    # FIXME: why is start_tls=0 used here?
    if options.user and options.password:
        lo = univention.admin.uldap.access(host=options.server, base=options.base, binddn=options.user, bindpw=options.password, start_tls=0)
    else:
        try:
            if ucr['server/role'] == 'domaincontroller_master':
                lo, _po = univention.admin.uldap.getAdminConnection(start_tls=0)
            else:
                lo, _po = univention.admin.uldap.getMachineConnection(start_tls=0)
        except OSError:
            print(_("Error: user and/or password not specified"), file=sys.stderr)
            parser.print_help(sys.stderr)
            sys.exit(1)

    report = Report(lo, config=cfg)

    try:
        filename = report.create(options.module, options.report, args)
    except ReportError as exc:
        print(_("Error: The %s report could not be created: %s") % (options.report, exc), file=sys.stderr)
        sys.exit(1)

    if not options.output_dir:
        options.output_dir = cfg.get_output_dir() or '/tmp'
    if not options.output_name:
        options.output_name = os.path.basename(filename)
    if not os.path.exists(options.output_dir):
        os.makedirs(options.output_dir, exist_ok=True)
    output_report = os.path.join(options.output_dir, options.output_name)
    filename = shutil.move(filename, output_report)

    print(_('The %s has been created: %s') % (options.report, filename))


if __name__ == "__main__":
    main()
