#!/usr/bin/env python3
"""
Configuring list moderators if scribe-backend is installed
"""

import sys
import re
from pathlib import Path
import itertools
from pyeole.service import manage_services
try:
    from scribe.eoleldap import get_etabs
    from scribe.eolegroup import (
            HAS_SYMPA, SYMPA_PATH, SYMPA_DATA_SOURCE_PATH,
            RACINE, GROUP_DN, EDITORS_GROUPS
            )
    from scribe.templates import tmpl_modo_request
except ImportError:
    sys.exit(0)

if not HAS_SYMPA:
    sys.exit(0)


editor_include_re = re.compile(r'editor_include\nsource (?P<source>.*)\n', re.M)
etab_re = re.compile(f'^suffix1.*ou=(?P<etab>.*?),{RACINE}', re.M | re.I)
eol_re = re.compile(r'\n{3,}', re.M)


def gen_editors_ldap_request(etab=None):
    # creation des filtres de éditeurs si besoin
    ldico = {}
    ldico['racine'] = RACINE
    for editor in EDITORS_GROUPS:
        ldico['modo_branche'] = GROUP_DN % dict(cn=editor, etab=etab)
        modo_request = tmpl_modo_request % ldico
        if etab is not None:
            editor = f"{etab}-{editor}"
        request_filter_path = Path(SYMPA_DATA_SOURCE_PATH).joinpath(f"ldap-{editor}.incl")
        if not request_filter_path.is_file():
            with open(request_filter_path, 'w') as request_filter:
                request_filter.write(modo_request)


def fix_editor_include(list_configuration, etabs, extended_groups=False):
    ldap_query_in_conf = 'include_ldap_2level_query' in list_configuration
    if extended_groups is True:
        editors_groups = itertools.product(etabs, EDITORS_GROUPS)
        fixed_editor_includes = "\n\n".join([f"editor_include\nsource ldap-{etab}-{eg}"
                                             for etab, eg in editors_groups])
    elif ldap_query_in_conf:
        etab_match = etab_re.search(list_configuration)
        etab = etab_match.group('etab')
        fixed_editor_includes = "\n\n".join([f"editor_include\nsource ldap-{etab}-{eg}"
                                             for eg in EDITORS_GROUPS])
    else:
        return None

    editor_includes = list(editor_include_re.finditer(list_configuration))
    keep_spans = []
    for span in sorted([ei.span() for ei in editor_includes]):
        if len(keep_spans) == 0 or span[0] > keep_spans[-1]:
            keep_spans.append(span[0])
            keep_spans.append(span[1])
        elif span[1] > keep_spans[-1]:
            keep_spans.pop()
            keep_spans.append(span[1])
    keep_spans.append(len(list_configuration))
    keep_spans = list(zip([0] + keep_spans[1::2],
                          keep_spans[:-1:2] + [len(list_configuration)]))
    keep_conf = '\n\n'.join([list_configuration[s:e] for s, e in keep_spans])
    keep_conf += '\n\n'
    keep_conf += fixed_editor_includes
    keep_conf += '\n'
    keep_conf = eol_re.sub('\n\n', keep_conf)
    return keep_conf


def main():
    try:
        etabs = get_etabs()
    except BaseException:
        print('Liste des établissements non disponibles pour la construction des filtres de liste de diffusion')
        sys.exit(1)

    etabs = [etabs[0]] + etabs[1]

    for etab in etabs:
        gen_editors_ldap_request(etab=etab)

    for category in SYMPA_PATH.values():
        for configuration in Path(category).glob('**/config'):
            with open(configuration, 'r') as conf_fh:
                conf = conf_fh.read()
            fixed_conf = fix_editor_include(conf, etabs, extended_groups=False)
            if fixed_conf:
                with open(configuration, 'w') as conf_fh:
                    conf_fh.write(fixed_conf)

    manage_services("restart", names=["sympa"], container="mail")


if __name__ == "__main__" and sys.argv[1] == "reconfigure":
    main()

sys.exit(0)
