---
- name: (apt.yml) Delete Hetzner files 'hetzner-mirror.list' and 'hetzner-security-updates.list'
  ansible.builtin.file:
    path: "{{ item }}"
    state: absent
  with_items:
    - /etc/apt/sources.list.d/hetzner-mirror.list
    - /etc/apt/sources.list.d/hetzner-security-updates.list
  tags:
    - apt-configuration

- name: (apt.yml) update configuration file - /etc/apt/sources.list
  ansible.builtin.template:
    src: "etc/apt/sources.list.{{ ansible_facts['distribution'] }}.j2"
    dest: /etc/apt/sources.list
    owner: root
    group: root
    mode: "0644"
  register: common_apt_config_updated
  when:
    - apt_manage_sources_list|bool
    - ansible_facts['distribution'] == 'Debian'
    - (ansible_facts['distribution_major_version'] | int) < 13
  tags:
    - apt-configuration

- name: (apt.yml) Ensure Debian archive keyring is present for deb822 Signed-By (Debian >= 13)
  ansible.builtin.apt:
    name: debian-archive-keyring
    state: present
  when:
    - apt_manage_sources_list|bool
    - ansible_facts['distribution'] == 'Debian'
    - (ansible_facts['distribution_major_version'] | int) >= 13
    - apt_deb822_use_signed_by | default(true) | bool
  tags:
    - apt-configuration

- name: (apt.yml) check if legacy /etc/apt/sources.list exists (Debian >= 13)
  ansible.builtin.stat:
    path: /etc/apt/sources.list
  register: common_apt_sources_list_stat
  when:
    - apt_manage_sources_list|bool
    - ansible_facts['distribution'] == 'Debian'
    - (ansible_facts['distribution_major_version'] | int) >= 13
  tags:
    - apt-configuration

- name: (apt.yml) backup legacy /etc/apt/sources.list before deb822 migration (Debian >= 13)
  ansible.builtin.copy:
    src: /etc/apt/sources.list
    dest: /etc/apt/sources.list.before-deb822
    remote_src: true
    force: false
    owner: root
    group: root
    mode: "0644"
  when:
    - apt_manage_sources_list|bool
    - ansible_facts['distribution'] == 'Debian'
    - (ansible_facts['distribution_major_version'] | int) >= 13
    - common_apt_sources_list_stat.stat.exists | default(false)
  register: common_apt_sources_list_backup
  tags:
    - apt-configuration

- name: (apt.yml) replace /etc/apt/sources.list with deb822 notice (Debian >= 13)
  ansible.builtin.copy:
    dest: /etc/apt/sources.list
    content: |
      # {{ ansible_managed }}
      #
      # Verwaltet via Ansible. Repositories liegen in /etc/apt/sources.list.d/*.sources (deb822).
      # Zielrelease: {{ ansible_facts['distribution_release'] }}
    owner: root
    group: root
    mode: "0644"
  register: common_apt_config_updated_sources_list
  when:
    - apt_manage_sources_list|bool
    - ansible_facts['distribution'] == 'Debian'
    - (ansible_facts['distribution_major_version'] | int) >= 13
  tags:
    - apt-configuration

- name: (apt.yml) configure deb822 Debian repository (Debian >= 13)
  ansible.builtin.template:
    src: "etc/apt/deb822/debian.sources.j2"
    dest: /etc/apt/sources.list.d/debian.sources
    owner: root
    group: root
    mode: "0644"
  register: common_apt_config_updated_debian_sources
  when:
    - apt_manage_sources_list|bool
    - ansible_facts['distribution'] == 'Debian'
    - (ansible_facts['distribution_major_version'] | int) >= 13
  tags:
    - apt-configuration

- name: (apt.yml) configure deb822 security repository (Debian >= 13)
  ansible.builtin.template:
    src: "etc/apt/deb822/security.sources.j2"
    dest: /etc/apt/sources.list.d/security.sources
    owner: root
    group: root
    mode: "0644"
  register: common_apt_config_updated_security_sources
  when:
    - apt_manage_sources_list|bool
    - ansible_facts['distribution'] == 'Debian'
    - (ansible_facts['distribution_major_version'] | int) >= 13
  tags:
    - apt-configuration

- name: (apt.yml) configure deb822 backports repository (Debian >= 13)
  ansible.builtin.template:
    src: "etc/apt/deb822/backports.sources.j2"
    dest: /etc/apt/sources.list.d/backports.sources
    owner: root
    group: root
    mode: "0644"
  register: common_apt_config_updated_backports_sources
  when:
    - apt_manage_sources_list|bool
    - ansible_facts['distribution'] == 'Debian'
    - (ansible_facts['distribution_major_version'] | int) >= 13
    - apt_backports_enable | default(false) | bool
  tags:
    - apt-configuration

# If 'backports' was enabled in a previous run but is now disabled.
#
- name: (apt.yml) remove deb822 backports repository when disabled (Debian >= 13)
  ansible.builtin.file:
    path: /etc/apt/sources.list.d/backports.sources
    state: absent
  register: common_apt_config_removed_backports_sources
  when:
    - apt_manage_sources_list|bool
    - ansible_facts['distribution'] == 'Debian'
    - (ansible_facts['distribution_major_version'] | int) >= 13
    - not (apt_backports_enable | default(false) | bool)
  tags:
    - apt-configuration

# Collect change states from all Debian >=13 deb822 source tasks so apt update
# can force a fresh cache refresh when repository files changed.
- name: (apt.yml) aggregate deb822 source changes (Debian >= 13)
  ansible.builtin.set_fact:
    common_apt_config_updated:
      changed: >-
        {{
          (common_apt_config_updated_sources_list.changed | default(false))
          or (common_apt_config_updated_debian_sources.changed | default(false))
          or (common_apt_config_updated_security_sources.changed | default(false))
          or (common_apt_config_updated_backports_sources.changed | default(false))
          or (common_apt_config_removed_backports_sources.changed | default(false))
        }}
  when:
    - apt_manage_sources_list|bool
    - ansible_facts['distribution'] == 'Debian'
    - (ansible_facts['distribution_major_version'] | int) >= 13
  tags:
    - apt-configuration

- name: (apt.yml) apt update
  ansible.builtin.apt:
    update_cache: true
    cache_valid_time: "{{ 0 if common_apt_config_updated is defined and common_apt_config_updated.changed else apt_update_cache_valid_time }}"
  when: apt_update|bool
  tags:
    - apt-update
    - apt-upgrade
    - apt-dpkg-configure
    - apt-initial-install
    - apt-microcode
    - apt-compiler-pkgs
    - apt-webserver-pkgs

- name: (apt.yml) Configure any half-installed packages 'dpkg --configure -a'
  ansible.builtin.command: dpkg --configure -a
  register: common_dpkg_configure
  changed_when: (common_dpkg_configure.stdout | default('')) | length > 0
  failed_when: common_dpkg_configure.rc != 0
  when: apt_dpkg_configure|bool
  tags:
    - apt-dpkg-configure
    - apt-initial-install
    - apt-microcode
    - apt-compiler-pkgs
    - apt-webserver-pkgs

- name: (apt.yml) apt upgrade
  ansible.builtin.apt:
    upgrade: "{{ apt_upgrade_type }}"
    update_cache: true
    dpkg_options: "{{ apt_upgrade_dpkg_options | join(',') }}"
  when: apt_upgrade|bool
  tags:
    - apt-upgrade
    - apt-initial-install
    - apt-microcode
    - apt-compiler-pkgs
    - apt-webserver-pkgs

- name: (apt.yml) Initial install debian packages (stretch)
  ansible.builtin.apt:
    name: "{{ apt_initial_install_stretch }}"
    state: "{{ apt_install_state }}"
  when:
    - apt_initial_install_stretch is defined and apt_initial_install_stretch|length > 0
    - ansible_facts['distribution'] == "Debian"
    - ansible_facts['distribution_major_version'] == "9"
  tags:
    - apt-initial-install

- name: (apt.yml) Initial install debian packages (buster)
  ansible.builtin.apt:
    name: "{{ apt_initial_install_buster }}"
    state: "{{ apt_install_state }}"
  environment:
    DEBIAN_FRONTEND: noninteractive
  when:
    - apt_initial_install_buster is defined and apt_initial_install_buster|length > 0
    - ansible_facts['distribution'] == "Debian"
    - ansible_facts['distribution_major_version'] == "10"
  tags:
    - apt-initial-install

- name: (apt.yml) Initial install debian packages (bullseye)
  ansible.builtin.apt:
    name: "{{ apt_initial_install_bullseye }}"
    state: "{{ apt_install_state }}"
  environment:
    DEBIAN_FRONTEND: noninteractive
  when:
    - apt_initial_install_bullseye is defined and apt_initial_install_bullseye|length > 0
    - ansible_facts['distribution'] == "Debian"
    - ansible_facts['distribution_major_version'] == "11"
  tags:
    - apt-initial-install

- name: (apt.yml) Initial install debian packages (bookworm)
  ansible.builtin.apt:
    name: "{{ apt_initial_install_bookworm }}"
    state: "{{ apt_install_state }}"
  environment:
    DEBIAN_FRONTEND: noninteractive
  when:
    - apt_initial_install_bookworm is defined and apt_initial_install_bookworm|length > 0
    - ansible_facts['distribution'] == "Debian"
    - ansible_facts['distribution_major_version'] == "12"
  tags:
    - apt-initial-install

- name: (apt.yml) Initial install debian packages (trixie)
  ansible.builtin.apt:
    name: "{{ apt_initial_install_trixie }}"
    state: "{{ apt_install_state }}"
  environment:
    DEBIAN_FRONTEND: noninteractive
  when:
    - apt_initial_install_trixie is defined and apt_initial_install_trixie|length > 0
    - ansible_facts['distribution'] == "Debian"
    - ansible_facts['distribution_major_version'] == "13"
  tags:
    - apt-initial-install

- name: (apt.yml) Initial install ubuntu packages (bionic)
  ansible.builtin.apt:
    name: "{{ apt_initial_install_bionic }}"
    state: "{{ apt_install_state }}"
  environment:
    DEBIAN_FRONTEND: noninteractive
  when:
    - ansible_facts['distribution'] == "Ubuntu"
    - ansible_facts['distribution_release'] == "bionic"
  tags:
    - apt-initial-install

- name: (apt.yml) Initial install ubuntu packages (xenial)
  ansible.builtin.apt:
    name: "{{ apt_initial_install_xenial }}"
    state: "{{ apt_install_state }}"
  environment:
    DEBIAN_FRONTEND: noninteractive
  when:
    - ansible_facts['distribution'] == "Ubuntu"
    - ansible_facts['distribution_release'] == "xenial"
  tags:
    - apt-initial-install

- name: (apt.yml) Initial install ubuntu packages (jammy)
  ansible.builtin.apt:
    name: "{{ apt_initial_install_jammy }}"
    state: "{{ apt_install_state }}"
  environment:
    DEBIAN_FRONTEND: noninteractive
  when:
    - ansible_facts['distribution'] == "Ubuntu"
    - ansible_facts['distribution_release'] == "jammy"
  tags:
    - apt-initial-install

- name: (apt.yml) Initial install ubuntu packages (noble)
  ansible.builtin.apt:
    name: "{{ apt_initial_install_ubuntu_noble }}"
    state: "{{ apt_install_state }}"
  environment:
    DEBIAN_FRONTEND: noninteractive
  when:
    - ansible_facts['distribution'] == "Ubuntu"
    - ansible_facts['distribution_release'] == "noble"
  tags:
    - apt-initial-install

# ---
# Microcode
# ---

- name: (apt.yml) Ensure we have CPU microcode from backports (debian stretch)
  ansible.builtin.apt:
    name: "{{ microcode_package }}"
    state: present
    default_release: "{{ ansible_facts['distribution_release'] }}-backports"
  when:
    - ansible_facts['distribution'] == "Debian"
    - ansible_facts['distribution_major_version'] == "9"
    - ansible_facts['processor']|string is search("Intel")
  tags:
    - apt-initial-install
    - apt-microcode

- name: (apt.yml) Install CPU microcode (debian buster/bullseye/bookworm/trixie)
  ansible.builtin.apt:
    name: "{{ microcode_package }}"
    state: present
    default_release: "{{ ansible_facts['distribution_release'] }}"
  when:
    - ansible_facts['distribution'] == "Debian"
    - ansible_facts['distribution_major_version'] == "10" or ansible_facts['distribution_major_version'] == "11"  or ansible_facts['distribution_major_version']
      == "12" or ansible_facts['distribution_major_version'] == "13"
    - ansible_facts['processor']|string is search("Intel")
  tags:
    - apt-initial-install
    - apt-microcode

- name: (apt.yml) Install CPU microcode (ubuntu bionic)
  ansible.builtin.apt:
    name: "{{ microcode_package }}"
    state: present
    default_release: "{{ ansible_facts['distribution_release'] }}"
  when:
    - ansible_facts['distribution'] == "Ubuntu"
    - ansible_facts['distribution_release'] == "bionic"
    - ansible_facts['processor']|string is search("Intel")
  tags:
    - apt-initial-install
    - apt-microcode

- name: (apt.yml) Install CPU microcode (ubuntu xenial)
  ansible.builtin.apt:
    name: "{{ microcode_package }}"
    state: present
    default_release: "{{ ansible_facts['distribution_release'] }}"
  when:
    - ansible_facts['distribution'] == "Ubuntu"
    - ansible_facts['distribution_release'] == "xenial"
    - ansible_facts['processor']|string is search("Intel")
  tags:
    - apt-initial-install
    - apt-microcode

- name: (apt.yml) Install CPU microcode (ubuntu jammy)
  ansible.builtin.apt:
    name: "{{ microcode_package }}"
    state: present
    default_release: "{{ ansible_facts['distribution_release'] }}"
  when:
    - ansible_facts['distribution'] == "Ubuntu"
    - ansible_facts['distribution_release'] == "jammy"
    - ansible_facts['processor']|string is search("Intel")
  tags:
    - apt-initial-install
    - apt-microcode

- name: (apt.yml) Install lxc_host related packages
  ansible.builtin.apt:
    name: "{{ apt_lxc_host_pkgs }}"
    state: "{{ apt_install_state }}"
  when:
    - groups['lxc_host']|string is search(inventory_hostname)
  tags:
    - apt-lxc-hosts-pkgs

- name: (apt.yml) Install docker related packages
  ansible.builtin.apt:
    name: "{{ apt_docker_host_pkgs }}"
    state: "{{ apt_install_state }}"
  when:
    - groups['docker_host']|string is search(inventory_hostname)
  tags:
    - apt-docker-hosts-pkgs

- name: (apt.yml) Install kvm_host related packages
  ansible.builtin.apt:
    name: "{{ apt_kvm_host_pkgs }}"
    state: "{{ apt_install_state }}"
  when:
    - groups['kvm_host']|string is search(inventory_hostname)
  tags:
    - apt-kvm-hosts-pkgs

- name: (apt.yml) Install kvm_host related packages only debian 10 (buster)
  ansible.builtin.apt:
    name: "{{ apt_kvm_host_buster_pkgs }}"
    state: "{{ apt_install_state }}"
  when:
    - groups['kvm_host']|string is search(inventory_hostname)
    - ansible_facts['distribution'] == "Debian"
    - ansible_facts['distribution_major_version'] == "10"
  tags:
    - apt-kvm-hosts-pkgs

- name: (apt.yml) Install compiler related packages
  ansible.builtin.apt:
    name: "{{ apt_compiler_pkgs }}"
    state: "{{ apt_install_state }}"
  when: install_compiler_pkgs|bool
  tags:
    - apt-compiler-pkgs

- name: (apt.yml) Install postgresql_server related packages
  ansible.builtin.apt:
    name: "{{ apt_postgresql_pkgs }}"
    state: "{{ apt_install_state }}"
  when: install_postgresql_pkgs|bool
  tags:
    - apt-postgresql-server-pkgs

- name: (apt.yml) Install webserver related packages (Debian <= 12)
  ansible.builtin.apt:
    name: "{{ apt_webserver_pkgs }}"
    state: "{{ apt_install_state }}"
  when:
    - install_webserver_pkgs|bool
    - ansible_facts['os_family'] == 'Debian'
    - ansible_facts['distribution_major_version'] | int <= 12
  tags:
    - apt-webserver-pkgs

- name: (apt.yml) Install webserver related packages (Debian >= 13)
  ansible.builtin.apt:
    name: "{{ apt_webserver_pkgs_trixie }}"
    state: "{{ apt_install_state }}"
  when:
    - install_webserver_pkgs|bool
    - ansible_facts['os_family'] == 'Debian'
    - ansible_facts['distribution_major_version'] | int >= 13
  tags:
    - apt-webserver-pkgs

- name: (apt.yml) Install samba related packages
  ansible.builtin.package:
    pkg: "{{ apt_install_server_samba }}"
    state: present
  when:
    - "groups['samba_server']|string is search(inventory_hostname)"
  tags:
    - samba-server

- name: (apt.yml) Install extra packages
  ansible.builtin.apt:
    name: "{{ apt_extra_pkgs }}"
    state: "{{ apt_install_state }}"
  when:
    - >-
      (apt_install_extra_pkgs is boolean and apt_install_extra_pkgs)
      or
      (apt_install_extra_pkgs is not boolean and (apt_install_extra_pkgs | default([]) | length > 0))
    - apt_extra_pkgs | default([]) | length > 0
  tags:
    - apt-extra-pkgs

- name: (apt.yml) Remove unwanted packages
  ansible.builtin.apt:
    name: "{{ apt_remove }}"
    state: absent
    purge: "{{ apt_remove_purge }}"
  tags:
    - apt-remove

- name: (apt.yml) autoremove
  ansible.builtin.apt:
    autoremove: true
    dpkg_options: "{{ apt_upgrade_dpkg_options | join(',') }}"
  when: apt_autoremove|bool
  tags:
    - apt-autoremove
    - apt-initial-install
    - apt-microcode
    - apt-compiler-pkgs
    - apt-webserver-pkgs

- name: (apt.yml) autoclean cache
  ansible.builtin.apt:
    autoclean: true
  when: apt_clean | bool
  tags:
    - apt-clean
    - apt-initial-install
    - apt-microcode
    - apt-compiler-pkgs
    - apt-mysql-server-pkgs
    - apt-webserver-pkgs

# Fix error if install/update of repository mysql-/mariadb-client breaks
# link '/etc/mysql/my.cnf' in case mysql/mariadb was installed from source
#
- name: (apt.yml) Check if file '/usr/local/mysql/etc/my.cnf' exists
  ansible.builtin.stat:
    path: /usr/local/mysql/etc/my.cnf
  register: common_usr_local_mysql_etc_my_cnf
  when: groups['mysql_server']|string is search(inventory_hostname) or groups['apache2_webserver']|string is search(inventory_hostname) or
    groups['nextcloud_server']|string is search(inventory_hostname)
  tags:
    - apt-webserver-pkgs
    - apt-mysql-server-pkgs
    - check_mysql_cnf

# - name: debug
#   debug:
#     msg:
#       - common_usr_local_mysql_etc_my_cnf.stst.exists = {{ common_usr_local_mysql_etc_my_cnf.stat.exists }}
#       - "Variable common_usr_local_mysql_etc_my_cnf: {{ common_usr_local_mysql_etc_my_cnf }}"
#   tags:
#     - check_mysql_cnf

- name: (apt.yml) Create a symbolic link /etc/my.cnf -> /usr/local/mysql/etc/my.cnf
  ansible.builtin.file:
    src: /usr/local/mysql/etc/my.cnf
    dest: /etc/mysql/my.cnf
    owner: root
    group: root
    state: link
  when:
    - (groups['mysql_server']|string is search(inventory_hostname) or groups['apache2_webserver']|string is search(inventory_hostname) or
      groups['nextcloud_server']|string is search(inventory_hostname))
    - common_usr_local_mysql_etc_my_cnf.stat.exists
  tags:
    - apt-webserver-pkgs
    - apt-mysql-server-pkgs
    - check_mysql_cnf
