---
# Variable configuration.
- name: Include OS-specific variables (Debian).
  ansible.builtin.include_vars: "{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_version.split('.')[0] }}.yml"
  when: ansible_facts.os_family == 'Debian'

- name: Include OS-specific variables (RedHat).
  ansible.builtin.include_vars: "{{ ansible_facts.os_family }}-{{ ansible_facts.distribution_version.split('.')[0] }}.yml"
  when:
    - ansible_facts.os_family == 'RedHat'
    - ansible_facts.distribution != 'Fedora'
    - ansible_facts.distribution != 'Amazon'

- name: Include OS-specific variables (Amazon).
  ansible.builtin.include_vars: "{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_major_version }}.yml"
  when: ansible_facts.distribution == 'Amazon'

- name: Include OS-specific variables (Fedora).
  ansible.builtin.include_vars: "{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_version.split('.')[0] }}.yml"
  when: ansible_facts.distribution == 'Fedora'

- name: Define postgresql_packages.
  ansible.builtin.set_fact:
    postgresql_packages: "{{ __postgresql_packages | list }}"
  when: postgresql_packages is not defined

- name: Define postgresql_version.
  ansible.builtin.set_fact:
    postgresql_version: "{{ __postgresql_version }}"
  when: postgresql_version is not defined

- name: Define postgresql_daemon.
  ansible.builtin.set_fact:
    postgresql_daemon: "{{ __postgresql_daemon }}"
  when: postgresql_daemon is not defined

- name: Define postgresql_data_dir.
  ansible.builtin.set_fact:
    postgresql_data_dir: "{{ __postgresql_data_dir }}"
  when: postgresql_data_dir is not defined

- name: Define postgresql_bin_path.
  ansible.builtin.set_fact:
    postgresql_bin_path: "{{ __postgresql_bin_path }}"
  when: postgresql_bin_path is not defined

- name: Define postgresql_config_path.
  ansible.builtin.set_fact:
    postgresql_config_path: "{{ __postgresql_config_path }}"
  when: postgresql_config_path is not defined

- name: Define postgresql_unix_socket_directories_mode.
  ansible.builtin.set_fact:
    postgresql_unix_socket_directories_mode: >-
      {{ __postgresql_unix_socket_directories_mode | default('02775') }}
  when: postgresql_unix_socket_directories_mode is not defined

- name: Define postgresql_log_dir.
  ansible.builtin.set_fact:
    # postgresql_global_config_options is an array but its keys are unique, so it can be converted to dict,
    # to easily get the value under the 'log_directory' key
    postgresql_log_dir: "{{ (postgresql_global_config_options | items2dict(key_name='option', value_name='value')).log_directory }}"

- name: Define postgresql_effective_log_dir, if postgresql_log_dir is absolute
  ansible.builtin.set_fact:
    postgresql_effective_log_dir: "{{ postgresql_log_dir }}"
  when: postgresql_log_dir is match("/")

- name: Define postgresql_effective_log_dir, if postgresql_log_dir is relative
  ansible.builtin.set_fact:
    postgresql_effective_log_dir: "{{ postgresql_data_dir }}/{{ postgresql_log_dir }}"
  when: postgresql_log_dir is not match("/")

# Very useful https://pgtune.leopard.in.ua/
- name: Add PostgresSQL optimizations to global config options list
  ansible.builtin.set_fact:
    postgresql_global_config_options: "{{ postgresql_global_config_options + [item] }}"
  loop:
    - option: listen_addresses
      value: "{{ posgtgresql_ipv4 | default(ansible_default_ipv4.address) }}"
    - option: port
      value: "{{ postgresql_ipv4_port | default('5432') }}"
    - option: max_connections
      value: "{{ (ansible_processor_vcpus * 100) | int }}"
    - option: max_worker_processes
      value: "{{ ansible_processor_vcpus * 2 | default(4) }}"
    - option: max_parallel_workers_per_gather
      value: "{{ (ansible_processor_vcpus / 2) | int | default(2) }}"
    - option: max_parallel_workers
      value: "{{ ansible_processor_vcpus | default(4) }}"
    - option: max_parallel_maintenance_workers
      value: 2
    - option: shared_buffers
      value: "{{ (ansible_memtotal_mb / 4) | int }}MB"
    - option: effective_cache_size
      value: "{{ (ansible_memtotal_mb * 3 / 4) | int }}MB"
    - option: maintenance_work_mem
      value: "{{ (ansible_memtotal_mb / 16) | int }}MB"
    - option: io_method
      value: io_uring
    - option: huge_pages
      value: try
    - option: random_page_cost
      value: 1
    - option: log_filename
      value: postgresql-%Y-%m-%d.log
    - option: autovacuum
      value: "on"
    - option: vacuum_truncate
      value: "on"
    - option: wal_level
      value: logical
    - option: wal_sync_method
      value: fdatasync
    - option: wal_compression
      value: lz4
    - option: wal_buffers
      value: "{{ ((ansible_memtotal_mb / 16) | int ) if (ansible_memtotal_mb / 16) < 16 else 16 }}MB"
    - option: checkpoint_completion_target
      value: "0.9"
    - option: max_wal_size
      value: 10GB
    - option: min_wal_size
      value: 50MB
    - option: max_wal_senders
      value: 15
    - option: max_replication_slots
      value: 30
    - option: timezone
      value: Europe/Moscow
    - option: timescaledb.enable_vectorized_aggregation
      value: "off"
