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

import sys
import re
from pathlib import Path
from creole.client import CreoleClient
from pyeole.service import manage_services
from pyeole.process import system_code

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)

creole_client = CreoleClient()
container_path_mail = Path(creole_client.get_creole('container_path_mail'))

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 d’é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")
        with open(request_filter_path, 'w') as request_filter:
            request_filter.write(modo_request)
        # fix ownership in container
        request_filter_path = re.sub('^' + container_path_mail.as_posix() + '/', '/', request_filter_path.as_posix())
        system_code(['chown', 'sympa:sympa', request_filter_path], container='mail')


def fix_editor_include(list_configuration, include_etab=False):
    ldap_query_in_conf = 'include_ldap_2level_query' in list_configuration
    if ldap_query_in_conf:
        if include_etab:
            etab_match = etab_re.search(list_configuration)
            etab = etab_match.group('etab')
            inclusion = f"{etab}-"
        else:
            inclusion = ""
        fixed_editor_includes = "\n\n".join([f"editor_include\nsource ldap-{inclusion}{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]

    if len(etabs) > 1:
        for etab in etabs:
            gen_editors_ldap_request(etab=etab)
    else:
        gen_editors_ldap_request()

    for category in SYMPA_PATH.values():
        for configuration in Path(container_path_mail).joinpath(Path(category)).glob('**/config'):
            with open(Path(container_path_mail).joinpath(configuration), 'r') as conf_fh:
                conf = conf_fh.read()
            include_etab = len(etabs) > 1
            fixed_conf = fix_editor_include(conf, include_etab=include_etab)
            if fixed_conf:
                with open(Path(container_path_mail).joinpath(configuration), 'w') as conf_fh:
                    conf_fh.write(fixed_conf)
                system_code(['chown', 'sympa:sympa', configuration], container='mail')

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


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

sys.exit(0)
