---
- name: Ensure ansible_facts required by role
  include_tasks: set_facts.yml

# Distribution defaults are different from the postfix defaults, hence need to
# reinstall the package
- name: Remove postfix package(s) to restore config {{ __postfix_packages }}
  when:
    - postfix_conf.previous is defined
    - postfix_conf.previous == "replaced"
    - not __postfix_is_ostree
  block:
  # It is assumed that the only package providing config files that might
  # be modified is postfix - if this is not so, then additional
  # packages need to be added to this check
    - name: Get status of package(s) {{ __postfix_packages }}
      command: rpm -V {{ item }} # noqa command-instead-of-module
      loop: "{{ __postfix_packages }}"
      register: __postfix_packages_status
      failed_when: false
      changed_when: false

    - name: Remove package(s) to reset original confs {{ __postfix_packages }}
      package:
        name: "{{ __postfix_packages }}"
        state: absent
      register: __postfix_erased
      when: __postfix_packages_status.results | rejectattr('stdout', 'match', '^package .* is not installed') | selectattr('stdout', 'search', ' /etc/postfix/.*[.]cf($|\n)') | list | length > 0

- name: Remove configuration for replacement
  when:
    - postfix_conf.previous | d() == "replaced"
    - __postfix_is_ostree | d(false)
  block:
  # It is assumed that the only package providing config files that might
  # be modified is postfix - if this is not so, then additional
  # packages need to be added to this check
    - name: Get status of config files
      command: rpm -V --nomtime {{ item }} # noqa command-instead-of-module
      loop: "{{ __postfix_packages }}"
      register: __postfix_packages_status
      failed_when: false
      changed_when: false

    - name: Remove config files - make empty
      copy:
        dest: "{{ item }}"
        content: "\n" # to make postconf -e happy
        mode: preserve
      loop: "{{ mod_cf_files }}"
      vars:
        mod_cf_files: "{{ __postfix_packages_status.results | map(attribute='stdout') | map('default', '') | map('regex_findall', ' (/etc/postfix/.*[.]cf)(?:$|\n)') | select | flatten | list }}"

- name: Configure firewall
  include_tasks: firewall.yml

- name: Configure selinux
  include_tasks: selinux.yml

- name: Install Postfix
  package:
    name: "{{ __postfix_packages }}"
    state: present
    use: "{{ (__postfix_is_ostree | d(false)) | ternary('ansible.posix.rhel_rpm_ostree', omit) }}"

- name: Get default database type from postconf
  command: postconf -h default_database_type
  changed_when: false
  register: __postfix_register_dbtype

- name: Set postfix_default_database_type
  set_fact:
    postfix_default_database_type: "{{ __postfix_register_dbtype.stdout | trim }}"

- name: Enable Postfix
  service:
    name: postfix
    state: started
    enabled: true

- name: Get current config
  command: postconf
  register: __postfix_register_config
  changed_when: false
  when: postfix_conf | dict2items | rejectattr('key', 'match', '^previous$') | list | items2dict | d({}) | length > 0

- name: Check given config against current config
  changed_when: false
  when:
    - postfix_conf | dict2items | rejectattr('key', 'match', '^previous$') | list | items2dict | d({}) | length > 0
    - __postfix_register_config is defined
    - __postfix_register_config.stdout_lines is defined
  set_fact:
    __postfix_has_config_changed: |-
      {% for key, val in postfix_conf.items() %}
      {%   if key != 'previous' %}
      {%     set space = ' ' if val else '' %}
      {%     set itemstr = '{} ={}{}'.format(key, space, val) %}
      {%     if itemstr not in __postfix_register_config.stdout_lines %}
      True itemstr {{ itemstr }} is not in __postfix_register_config
      {%     endif %}
      {%   endif %}
      {% endfor %}

- name: Configure additional files
  copy:
    content: "{{ file['content'] }}"
    dest: /etc/postfix/{{ file['name'] }}
    owner: root
    group: root
    mode: '0640'
  loop: "{{ postfix_files }}"
  register: __postfix_postmap_files
  no_log: true
  loop_control:
    loop_var: file
  notify:
    - Check postfix
    - Restart postfix

- name: Postmap files
  command: postmap {{ result["dest"] | quote }}
  when:
    - result["changed"]
    - result["file"]["postmap"] | d(false)
  no_log: true
  changed_when: true
  loop: "{{ __postfix_postmap_files['results'] }}"
  loop_control:
    loop_var: result

- name: Apply changes
  when: __postfix_has_config_changed | d("") is search("True")
  block:
    - name: Gather facts for ansible_date_time
      setup:
        filter:
          - ansible_date_time
      when: postfix_backup_multiple | bool

    - name: Backup configuration
      copy:
        remote_src: true
        src: /etc/postfix/main.cf
        dest: /etc/postfix/main.cf.{{ postfix_backup_multiple | ternary(ansible_date_time.iso8601, "backup") }}
        mode: "0644"
      when: postfix_backup or postfix_backup_multiple

    - name: Ensure Last modified header is absent
      lineinfile:
        path: /etc/postfix/main.cf
        regexp: '# Last modified:'
        state: absent

  # Previously, the role inserted a plain-text comment at the top of main.cf.
  # This task removes this outdated header for compatibility.
    - name: Ensure the outdated ansible managed header is absent
      lineinfile:
        path: /etc/postfix/main.cf
        regexp: "# This file is managed by [aA]nsible"
        state: absent

    - name: Ensure ansible_managed header in configuration file
      vars:
        __lsr_ansible_managed: "{{ lookup('template', 'get_ansible_managed.j2') }}"
      blockinfile:
        path: /etc/postfix/main.cf
        block: "{{ __lsr_ansible_managed }}"
        insertbefore: BOF

    - name: Configure Postfix
      command: postconf -e {{ item.key | quote }}={{ item.value | quote }}
      notify:
        - Check postfix
        - Restart postfix
      with_dict: "{{ postfix_conf }}"
      when:
        - item.key not in ['previous']
        - __postfix_has_config_changed | d("") is search("True itemstr " ~ item.key)
      changed_when:
        - item.key not in ['previous']
        - __postfix_has_config_changed | d("") is search("True itemstr " ~ item.key)
