---
- name: Test we can handle all configuration options documented in manual page
  hosts: all
  gather_facts: true
  vars:
    __sshd_test_backup_files:
      - /etc/dnf/dnf.conf
      - /etc/yum.conf
      - /tmp/sshd_config
    sshd_c: {}
    sshd_skip_test: false
    pkg_mgr: "{{ 'dnf' if ansible_facts['distribution_version'] | int > 7 else 'yum' }}"
  tasks:
    - name: Backup configuration files
      ansible.builtin.include_tasks: tasks/backup.yml

    - name: Skip test on EL6 as it has some crippled manpages
      ansible.builtin.set_fact:
        sshd_skip_test: true
      when:
        - ansible_facts['os_family'] == "RedHat"
        - ansible_facts['distribution_version'] | int <= 6

    - name: Enable installation of manual pages on Fedora/RHEL
      ansible.builtin.lineinfile:
        line: tsflags=nodocs
        path: "{{ '/etc/dnf/dnf.conf' if ansible_facts['distribution_version'] | int > 7 else '/etc/yum.conf' }}"
        state: absent
      when:
        - ansible_facts['os_family'] == "RedHat"
        - not __sshd_is_ostree | d(false)

    - name: Reinstall manual pages for openssh-server on RHEL
      ansible.builtin.command: "{{ pkg_mgr | quote }} reinstall -y openssh-server"
      when:
        - ansible_facts['os_family'] == "RedHat"
        - not __sshd_is_ostree | d(false)
      changed_when: true

    - name: Unminimize image on Debian. It looks like there is no simpler way to get manual pages
      ansible.builtin.shell: set -eu; set -o | grep -q pipefail && set -o pipefail; yes | unminimize
      when:
        - ansible_facts['distribution'] == "Ubuntu"
      changed_when: true

    - name: Make sure manual pages and bash are installed on Alpine
      ansible.builtin.package:
        name:
          - mandoc
          - man-pages
          - openssh-doc
          - bash
        state: present
        use: "{{ (__sshd_is_ostree | d(false)) | ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
      when:
        - ansible_facts['distribution'] == "Alpine"

    - name: Make sure manual pages, gawk and bash are installed on RedHat 7+
      ansible.builtin.package:
        name:
          - man-db
          - bash
          - gawk
        state: present
        use: "{{ (__sshd_is_ostree | d(false)) | ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
      when:
        - ansible_facts['os_family'] == "RedHat"
        - ansible_facts['distribution_major_version'] | int > 6

    - name: Make sure manual pages, gawk and bash are installed elsewhere
      ansible.builtin.package:
        name:
          - man
          - bash
          - gawk
        state: present
        use: "{{ (__sshd_is_ostree | d(false)) | ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
      when:
        - ansible_facts['distribution'] != "Alpine"
        - ansible_facts['os_family'] != "RedHat" or ansible_facts['distribution_major_version'] | int == 6

    - name: Show list of options from manual page
      ansible.builtin.shell: >-
        set -eu; set -o | grep -q pipefail && set -o pipefail; man sshd_config | cat
      changed_when: false

    - name: Get list of options from manual page
      ansible.builtin.shell: >-
        set -o pipefail && man sshd_config \
          | sed 's/\x08.//g' \
          | grep -o '^\(     \|       \)[A-Z][A-Za-z0-9]*\(.\|  \)' \
          | grep -v "[A-Za-z0-9] $" | grep -v "[^A-Za-z0-9 ]$" \
          | awk '{ print $1 }' \
          | grep -v '^$' | grep -v "^\(Match\|OpenSSH\|The\|Arguments\|Theo\|Tatu\|Aaron\|Each\)$"
      args:
        executable: /bin/bash
      register: sshd_options
      changed_when: false
      when: not sshd_skip_test

    - name: Print all the possible options
      ansible.builtin.debug:
        var: sshd_options.stdout_lines

    - name: Construct the configuration list
      ansible.builtin.set_fact:
        sshd_c: "{{ sshd_c | combine({item: 'yes'}) }}"
      loop: "{{ sshd_options.stdout_lines }}"
      when: not sshd_skip_test

    - name: Run role
      ansible.builtin.include_role:
        name: fedora.linux_system_roles.sshd
      vars:
      # The configuration is not valid as we are using bogus values
        __sshd_supports_validate: false
      # The hostkeys are not valid either so do not validate them
        sshd_verify_hostkeys: []
        sshd_config_file: /tmp/sshd_config
        sshd_config: "{{ sshd_c }}"
      when: not sshd_skip_test

    - name: Download the configuration file
      ansible.builtin.slurp:
        src: /tmp/sshd_config
      register: config
      when: not sshd_skip_test

    - name: Verify the options are in the file
      ansible.builtin.assert:
        that: item ~ " yes" in config.content | b64decode
      loop: "{{ sshd_options.stdout_lines }}"
      when: not sshd_skip_test

    - name: Check generated files for ansible_managed, fingerprint
      ansible.builtin.include_tasks: tasks/check_header.yml
      vars:
        __file_content: "{{ config }}"
        __fingerprint: "willshersystems:ansible-sshd"
      when: not sshd_skip_test

    - name: Restore configuration files
      ansible.builtin.include_tasks: tasks/restore.yml
