---
- name: "include docker-compose role"
  include_role: 
    name: docker-compose

- name: Create {{domains[application_id]}}.conf if LDAP is exposed to internet
  template: 
    src:  "nginx.stream.conf.j2" 
    dest: "{{nginx.directories.streams}}{{domains[application_id]}}.conf"
  notify: restart nginx
  when: applications.ldap.network.public | bool

- name: Remove {{domains[application_id]}}.conf if LDAP is not exposed to internet
  file:
    path: "{{ nginx.directories.streams }}{{ domains[application_id] }}.conf"
    state: absent
  when: not applications.ldap.network.public | bool

- name: create docker network for LDAP, so that other applications can access it
  docker_network:
    name: central_ldap
    state: present
    ipam_config:
      - subnet: "{{ networks.local.central_ldap.subnet }}"
  
- name: "copy docker-compose.yml and env file"
  include_tasks: copy-docker-compose-and-env.yml

- name: "create directory {{ldif_host_path}}{{item}}"
  file:
    path: "{{ldif_host_path}}{{item}}"
    state: directory
    mode: 0755
  loop: "{{ldif_types}}"

- name: "Process all LDIF types"
  include_tasks: create_ldif_files.yml
  loop:
    - configuration
  loop_control:
    loop_var: folder

- name: flush LDIF handlers
  meta: flush_handlers

- name: install python-ldap
  community.general.pacman:
    name:
      - python-ldap
    state: present

- name: Create Nextcloud Schema
  ldap_entry:
    dn: "cn=nextcloud,cn=schema,cn=config"
    objectClass:
      - top
      - olcSchemaConfig
    attributes:
      cn: nextcloud
      olcAttributeTypes:
        - >-
          ( 1.3.6.1.4.1.99999.1
            NAME 'nextcloudQuota'
            DESC 'Quota for Nextcloud'
            EQUALITY integerMatch
            ORDERING integerOrderingMatch
            SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
            SINGLE-VALUE
          )
      olcObjectClasses:
        - >-
          ( 1.3.6.1.4.1.99999.2
            NAME 'nextcloudUser'
            DESC 'Auxiliary class for Nextcloud attributes'
            AUXILIARY
            MAY ( nextcloudQuota )
          )
    server_uri: "ldap://127.0.0.1:{{ ports.localhost.ldap.ldap }}"
    bind_dn: "cn={{ applications.ldap.users.administrator.username }},cn=config"
    bind_pw: "{{ applications.ldap.administrator_password }}"
    state: present

###############################################################################
# 1) Create the LDAP entry if it does not yet exist
###############################################################################
- name: Ensure LDAP users exist
  community.general.ldap_entry:
    dn: "{{ ldap.attributes.user_id }}={{ item.key }},{{ ldap.dn.users }}"
    server_uri: "ldap://127.0.0.1:{{ ports.localhost.ldap.ldap }}"
    bind_dn: "{{ ldap.dn.administrator }}"
    bind_pw: "{{ ldap.bind_credential }}"
    objectClass: "{{ ldap.user_objects }}"
    attributes:
      uid:           "{{ item.key }}" # {{ ldap.attributes.user_id }} can't be used as key here, dynamic key generation isn't possible
      sn:            "{{ item.value.sn  | default(item.key) }}"
      cn:            "{{ item.value.cn  | default(item.key) }}"
      userPassword:  "{SSHA}{{ item.value.password }}"
      loginShell:    /bin/bash
      homeDirectory: "/home/{{ item.key }}"
      uidNumber:     "{{ item.value.uid | int }}"
      gidNumber:     "{{ item.value.gid | int }}"
    state: present            # ↳ creates but never updates
  loop: "{{ users | dict2items }}"
  loop_control:
    label: "{{ item.key }}"

###############################################################################
# 2) Keep the objectClass list AND the mail attribute up-to-date
###############################################################################
- name: Ensure required objectClass values and mail address are present
  community.general.ldap_attrs:
    dn: "{{ ldap.attributes.user_id }}={{ item.key }},{{ ldap.dn.users }}"
    server_uri: "ldap://127.0.0.1:{{ ports.localhost.ldap.ldap }}"
    bind_dn: "{{ ldap.dn.administrator }}"
    bind_pw: "{{ ldap.bind_credential }}"
    attributes:
      objectClass: "{{ ldap.user_objects }}"
      mail:         "{{ item.value.email }}"
    state: exact        # ‘exact’ is safest for single-valued attributes
  loop: "{{ users | dict2items }}"
  loop_control:
    label: "{{ item.key }}"

- name: "Ensure container for application roles exists"
  community.general.ldap_entry:
    dn: "{{ ldap.dn.application_roles }}"
    server_uri: "ldap://127.0.0.1:{{ ports.localhost.ldap.ldap }}"
    bind_dn:  "{{ ldap.dn.administrator }}"
    bind_pw:  "{{ ldap.bind_credential }}"
    objectClass: organizationalUnit
    attributes:
      ou: roles
      description: Container for application access profiles
    state: present

- name: "Process all LDIF types"
  include_tasks: create_ldif_files.yml
  loop:
    - data
  loop_control:
    loop_var: folder