#!/usr/bin/python3
#
# Univention AD Connector
#  List all rejected objects
#
# SPDX-FileCopyrightText: 2004-2026 Univention GmbH
# SPDX-License-Identifier: AGPL-3.0-only


import argparse
import sys
import textwrap

import ldap

import univention.config_registry
import univention.connector.ad


def parse_args():
    parser = argparse.ArgumentParser(
        description="Summarize objects rejected due to sync failures.",
        add_help=True,
    )

    parser.add_argument(
        "-c", "--configbase",
        default="connector",
        help='Configuration base to use (default: "connector")',
    )

    parser.add_argument(
        "-v", "--verbose",
        action="store_true",
        help="Enable verbose output",
    )

    return parser.parse_args()


def main():
    args = parse_args()
    configRegistry = univention.config_registry.ConfigRegistry()
    configRegistry.load()

    ad = univention.connector.ad.ad.main(configRegistry, args.configbase)
    max_retry_rejected = configRegistry.get('%s/ad/max_retry_rejected' % (args.configbase,), 10)
    try:
        ad.init_ldap_connections()
    except ldap.SERVER_DOWN as exc:
        print('WARNING: LDAP server could not be reached: %s' % (exc,), file=sys.stderr)
        sys.exit(1)

    found_rejected = False
    i = 1
    print("\nUCS rejected\n")
    for filename, dn in ad.list_rejected_ucs():
        found_rejected = True
        print("%5d:   UCS DN: %s" % (i, dn))
        ad_dn = ad.get_dn_by_ucs(dn)
        if ad_dn:
            print("          AD DN: %s" % ad_dn)
        else:
            print("          AD DN: <not found>")
        print("         Filename: %s\n" % filename)
        i += 1

    i = 1
    print("\nAD rejected\n")
    for _id, dn, retry_count in ad.list_rejected():
        found_rejected = True
        print("%5d:    AD DN: %s" % (i, dn))
        ucs_dn = ad.get_dn_by_con(dn)
        reason = ad._get_reject_reason(_id)
        if ucs_dn:
            print("         UCS DN: %s" % ucs_dn)
        else:
            print("         UCS DN: <not found>")
        try:
            print("         Reason: %s" % reason.splitlines()[0])
        except IndexError:
            # No reason stored in DB
            pass
        if args.verbose:
            try:
                print(textwrap.indent("%s" % "\n".join(reason.splitlines()[1:]), 17 * " "))
            except IndexError:
                # Single line reason
                pass
        print("         tried: %s/%s times\n" % (retry_count, max_retry_rejected))
        i += 1

    if not found_rejected:
        print("\nThere may be no rejected DNs if the connector is in progress, to be\nsure stop the connector before running this script.\n")

    print("\n\tlast synced USN: %s" % ad.get_lastUSN())


if __name__ == "__main__":
    main()
