#!/usr/bin/python3
# -*- coding: utf-8 -*-
#
# Univention UCS@school
#
# SPDX-FileCopyrightText: 2018-2026 Univention GmbH
# SPDX-License-Identifier: AGPL-3.0-only

import argparse
import csv
import logging
import sys

from ucsschool.lib.create_ou import create_ou
from ucsschool.lib.models.utils import get_stream_handler, ucr
from univention.admin.uexceptions import uidAlreadyUsed
from univention.admin.uldap import getAdminConnection


def main():
    parser = argparse.ArgumentParser(description="create school container for UCS@school")
    parser.add_argument(
        "--sharefileserver",
        help="hostname of the fileserver within given OU that is used for class shares and user home "
        "shares",
    )
    parser.add_argument(
        "--displayName",
        help="Descriptive name of the school OU that is shown within UCS@school modules as school name "
        '(e.g. "Gymnasium Mitte")',
    )
    parser.add_argument(
        "--infile",
        help="CSV file for mass import of ou's. Format is ou_name,display_name,edu_name,admin_name,"
        "share_name. If given parameters are overwritten.",
    )
    parser.add_argument(
        "--alter-dhcpd-base",
        choices=("true", "false", "auto"),
        default="auto",
        help="This option sets whether the UCR variable dhcpd/ldap/base should be modified during school"
        " creation on singleserver environments."
        " The possible values are true, false and auto.",
    )
    parser.add_argument("-v", "--verbose", action="store_true", help="Display debug output.")
    parser.add_argument("ou_name", nargs="?", help="name of ou that shall be created or verified")
    parser.add_argument(
        "educational_dc_name",
        nargs="?",
        help='hostname of the educational DC for specified OU (if dc_name is not specified "dc<ou_name>"'
        " will beused as the default for the domaincontroller name)",
    )
    parser.add_argument(
        "administrative_dc_name",
        nargs="?",
        help="hostname of the administrative DC for the specified OU",
    )
    options = parser.parse_args()
    logger = logging.getLogger("ucsschool")
    log_level = "DEBUG" if options.verbose else "INFO"
    logger.setLevel(log_level)
    logger.addHandler(get_stream_handler(log_level))
    ou_tuples = []  # (ou_name,display_name,edu_name,admin_name,share_name)
    alter_dhcpd_base = None
    if options.alter_dhcpd_base == "true":
        alter_dhcpd_base = True
    elif options.alter_dhcpd_base == "false":
        alter_dhcpd_base = False
    if options.infile:
        try:
            with open(options.infile) as fd:
                reader = csv.reader(fd, delimiter=",")
                for row in reader:
                    if len(row) != 5:
                        logger.warning("WARNING: Malformed row for %r will be ignored!", row[0])
                    ou_tuples.append(tuple(e if e != "" else None for e in row))
        except IOError as exc:
            logger.error("ERROR: The given file could not be parsed:")
            logger.error(exc)
            sys.exit(1)
    elif options.ou_name:
        ou_tuples.append(
            (
                options.ou_name,
                options.displayName,
                options.educational_dc_name,
                options.administrative_dc_name,
                options.sharefileserver,
            )
        )
    else:
        parser.print_help()
        sys.exit(1)
    if not ou_tuples:
        parser.print_help()
        sys.exit(1)

    baseDN = ucr["ldap/base"]
    is_single_master = ucr.is_true("ucsschool/singlemaster", False)
    hostname = ucr.get("hostname")
    lo, pos = getAdminConnection()
    exit_value = 0

    for ou_name, display_name, edu_name, admin_name, share_name in ou_tuples:
        logger.info("Create OU: %r", ou_name)
        try:
            create_ou(
                ou_name,
                display_name,
                edu_name,
                admin_name,
                share_name,
                lo,
                baseDN,
                hostname,
                is_single_master,
                alter_dhcpd_base,
            )
        except (ValueError, uidAlreadyUsed) as exc:
            logger.error(exc)
            logger.error("Skip OU: %r", ou_name)
            exit_value = 1
        else:
            logger.info("Created OU: %r", ou_name)
    sys.exit(exit_value)


if __name__ == "__main__":
    main()
