---

- name: Check role exists
  become: yes
  become_user: postgres
  shell: "/usr/bin/psql -Atc \"SELECT count(rolname) FROM pg_roles where rolname='replicator'\"" # noqa command-instead-of-shell
  register: role_check
  ignore_errors: yes # noqa ignore-errors no-changed-when

- name: Create role if necessary
  become: yes
  become_user: postgres
  shell: "/usr/bin/psql -c 'CREATE ROLE replicator WITH REPLICATION LOGIN;'"
  when: role_check.stdout == "0"
  ignore_errors: yes # noqa ignore-errors

- name: Change password with scram-sha-256! for replicator and set password
  become: yes
  become_user: postgres
  shell: "/usr/bin/psql -c \"set password_encryption = 'scram-sha-256';ALTER ROLE replicator WITH PASSWORD '{{ postgres_replicator_user_password }}';\""
  ignore_errors: yes # noqa ignore-errors no-changed-when

- name: Setup pg_hba.conf for replicator user
  lineinfile:
    state: present
    regex: "^host[ ]+replication[ ]+replicator"
    line: "host    replication     replicator      {{ shared_service_pg_slave_ip }}/32     trust"
    path: /etc/postgresql/{{ default_postgres_version }}/main/pg_hba.conf
  register: pg_hba_conf_replicator

- name: Set 'wal_level = replica' for master postgresql instance
  lineinfile:
    state: present
    regex: "^wal_level"
    line: "wal_level = replica"
    path: /etc/postgresql/{{ default_postgres_version }}/main/postgresql.conf
  register: wal_level

- name: Set 'max_wal_senders = 10' for master postgresql instance
  lineinfile:
    state: present
    regex: "^max_wal_senders"
    line: "max_wal_senders = 10"
    path: /etc/postgresql/{{ default_postgres_version }}/main/postgresql.conf
  register: max_wal_senders

- name: Set 'archive_mode = on' for master postgresql instance
  lineinfile:
    state: present
    regex: "^archive_mode"
    line: "archive_mode = on"
    path: /etc/postgresql/{{ default_postgres_version }}/main/postgresql.conf
  register: archive_mode

- name: Set 'archive_command = cp -f %p /postgresql/replication/%f' for master postgresql instance
  lineinfile:
    state: present
    regex: "^archive_command"
    line: "archive_command = 'cp -f %p /postgresql/replication/%f'"
    path: /etc/postgresql/{{ default_postgres_version }}/main/postgresql.conf
  register: archive_command

- name: Set 'wal_keep_size  = 16' for master postgresql instance
  lineinfile:
    state: present
    regex: "^wal_keep_size"
    line: "wal_keep_size = 16"
    path: /etc/postgresql/{{ default_postgres_version }}/main/postgresql.conf
  register: wal_keep_size

- name: Install nfs-server
  apt: name=nfs-kernel-server state=present update_cache=yes cache_valid_time=900

- name: Install nfs-common
  apt: name=nfs-common state=present update_cache=yes cache_valid_time=900

- name: Create nfs share for archive
  lineinfile:
    path: /etc/exports
    regex: "^/postgresql/replication"
    line: "/postgresql/replication/ {{ shared_service_pg_slave_ip }}/32(rw,crossmnt,root_squash,no_subtree_check,sync)"
    state: present
  register: nfsshare_archive_check

- name: Restart nfs-server if necessary # noqa no-handler
  service:
    name: nfs-kernel-server
    state: restarted
  when: nfsshare_archive_check.changed

- name: Restart postgres if necessary # noqa no-handler
  service:
    name: postgresql
    state: restarted
  when:
    pg_hba_conf_replicator.changed or
    wal_level.changed or
    archive_mode.changed or
    archive_command.changed or
    max_wal_senders.changed or
    wal_keep_size.changed

- name: Create extension pgcrypto for template1
  become: yes
  become_user: postgres
  shell: "/usr/bin/psql template1 -c \"create extension if not exists pgcrypto;\""
  ignore_errors: yes # noqa ignore-errors no-changed-when

- name: Check database replication_cron exists
  become: yes
  become_user: postgres
  shell: "/usr/bin/psql -Atc \"SELECT count(*) FROM pg_database WHERE datname = 'replication_cron'\""
  register: database_replication_check
  ignore_errors: yes # noqa ignore-errors no-changed-when

- name: Create replication_cron update database
  become: yes
  become_user: postgres
  shell: "/usr/bin/psql -c \"CREATE DATABASE replication_cron;\""
  when: database_replication_check.stdout == "0"
  ignore_errors: yes # noqa ignore-errors no-changed-when

- name: Create replication update schema
  become: yes
  become_user: postgres
  shell: "/usr/bin/psql replication_cron -c \"CREATE SCHEMA IF NOT EXISTS replication_cron;\""
  ignore_errors: yes # noqa ignore-errors no-changed-when

- name: Create replication update table
  become: yes
  become_user: postgres
  shell: "/usr/bin/psql replication_cron -c \"CREATE TABLE IF NOT EXISTS replication_cron.replication_cron (dt timestamp);\""
  ignore_errors: yes # noqa ignore-errors no-changed-when

- name: Create dummy update data
  become: yes
  become_user: postgres
  shell: "/usr/bin/psql replication_cron -c \"INSERT INTO replication_cron.replication_cron SELECT now() WHERE NOT EXISTS (SELECT 1 from replication_cron.replication_cron);\""
  ignore_errors: yes # noqa ignore-errors no-changed-when

- name: Ensure a cron runs every 5 minutes and update replication check table"
  ansible.builtin.cron:
    name: "update replication table"
    minute: "*/5"
    job: su - postgres -c "/usr/bin/psql replication_cron -c \"UPDATE replication_cron.replication_cron SET dt=now();\""

- name: Check replication slot exists
  become: yes
  become_user: postgres
  shell: "/usr/bin/psql -Atc \"select count(*) from pg_replication_slots where slot_name='pgstandby1'\""
  register: replication_slot_check
  ignore_errors: yes # noqa ignore-errors no-changed-when

- name: Create replication-slot
  become: yes
  become_user: postgres
  shell: "/usr/bin/psql -Atc \"SELECT pg_create_physical_replication_slot('pgstandby1');\""
  ignore_errors: yes # noqa ignore-errors
  when: replication_slot_check.stdout == "0"


# only needed in case of install from scratch
- name: "Ensure test db stuff"
  block:
  - name: "Copy testdb.sql to ensure test DB"
    copy:
      src: '{{ item }}'
      dest: '/tmp/{{ item }}'
      mode: '0444'
      owner: postgres
      group: postgres
    loop:
      - testdb.sql

  - name: "Ensure test DB"
    become: yes
    become_user: postgres
    community.postgresql.postgresql_db:
      name: dummytestdb

  - name: "Ensure content for test DB"
    become: yes
    become_user: postgres
    community.postgresql.postgresql_db:
      name: dummytestdb
      state: restore
      target: /tmp/testdb.sql

  when: postgres_ensure_testdb | default(False)
