#!/usr/bin/python3
# -*- coding: utf-8 -*-

import logging
import re
import traceback

from univention.admin.hook import simpleHook

from ucsschool.lib.models.utils import get_file_handler

LOG_FILE = "/var/log/univention/ucsschool-user-group-transfers.log"
LIMBO_OU = "limbo"


class UcsschoolUserGroupTransfers(simpleHook):
    type = "UcsschoolUserGroupTransfers"

    def __init__(self):
        super().__init__()
        self.regex = re.compile(r".*,ou={},.*".format(LIMBO_OU))
        self.logger = logging.getLogger("UcsschoolUserGroupTransfers")
        self.logger.setLevel("DEBUG")
        if not self.logger.handlers:
            self.logger.addHandler(get_file_handler("DEBUG", LOG_FILE, uid=0, gid=0))

    def hook_ldap_pre_modify(self, obj):
        if LIMBO_OU not in obj.info.get("school", []):
            return
        is_school_obj = (
            "ucsschoolStudent" in obj.options or "ucsschoolTeacher" in obj.options
        )
        if is_school_obj:
            new_groups = set(obj.info.get("groups", []))
            old_groups = set(
                [group.decode() for group in obj.oldattr.get("memberOf", [])]
            )
            if new_groups != old_groups:
                # We are only interested in group changes.
                self.logger.debug("DN: {}".format(obj.dn))
                self.logger.debug("Old groups: {}".format(old_groups))
                self.logger.debug("New groups: {}".format(new_groups))
                # Might also be interesting:
                # self.logger.debug("Roles: {}".format(obj.info.get("ucsschoolRole")))
                # self.logger.debug("Schools: {}".format(obj.info.get("school")))
            else:
                return
            non_limbo_school_groups = [
                group for group in new_groups if not re.match(self.regex, group)
            ]
            if non_limbo_school_groups:
                stack_trace = " ".join(traceback.format_stack()).replace("\n", " ")
                self.logger.warning(
                    "NOK: Groups from schools other than {}: {}".format(
                        LIMBO_OU, non_limbo_school_groups
                    )
                )
                self.logger.warning("Stacktrace: {}".format(stack_trace))
