# SPDX-License-Identifier: MIT
---
# Verify if constraint.resource.id exists
- name: Verify resource presence {{ constraint.resource.id }}
  ansible.builtin.command:
    cmd: >-
      crm -c {{ __ha_cluster_crm_shadow }}
      configure show {{ constraint.resource.id }}
  register: __ha_cluster_constraint_resource
  changed_when: false
  when: constraint.resource.pattern is not defined
  failed_when:
    - "'does not exist' in __ha_cluster_constraint_resource.stderr"

- name: Define location constraint.id {{ constraint.id | d(constraint_index) }}
  ansible.builtin.set_fact:
    __ha_cluster_constraint_id:
      "{{ constraint.id if constraint.id is defined
        else 'loc_' +
         (constraint.resource.pattern | regex_replace('[^A-Za-z0-9]', '')
         | quote)
      if constraint.resource.pattern is defined
      else 'loc_' + (constraint.resource.id | quote) }}"

# Verify if Shadow CIB already contains same constraint id.
- name: Verify location constraint presence {{ __ha_cluster_constraint_id }}
  ansible.builtin.command:
    cmd: >-
      crm -c {{ __ha_cluster_crm_shadow }}
      configure show {{ __ha_cluster_constraint_id }}
  register: __ha_cluster_constraint_status
  changed_when: false
  failed_when: false

# Delete constraint id in Shadow CIB to avoid errors during cibadmin patch.
- name: Delete present location constraint {{ __ha_cluster_constraint_id }}
  ansible.builtin.command:
    cmd: >-
      crm --force -c {{ __ha_cluster_crm_shadow }}
      configure delete {{ __ha_cluster_constraint_id }}
  when: __ha_cluster_constraint_status.rc == 0
  check_mode: false
  changed_when: not ansible_check_mode

# Expect module is used to combat crmsh freezing when asking for user input
- name: Configure location constraint {{ __ha_cluster_constraint_id }}
  ansible.builtin.expect:
    command: |
      crm -c {{ __ha_cluster_crm_shadow }}
      configure location {{ __ha_cluster_constraint_id }}
      {% if constraint.resource.pattern | d() %}
        /{{ constraint.resource.pattern | quote }}/
      {% else %}
        {{ constraint.resource.id | quote }}
      {% endif %}\
      {% if constraint.resource.role | d() and
        constraint.resource.role | lower in __ha_cluster_crmsh_roles %}
          role={{
            constraint.resource.role | lower | capitalize | quote
          }}
        {% endif %}
      rule
      {% for option in constraint.options | d([]) if option.name == 'score' %}
        {{ option.value | lower | replace('infinity', 'inf') | quote }}:
      {% else %}
        inf:
      {% endfor %}
      {% if constraint.rule | d() %}
        rule {{ constraint.rule }}
      {% else %}
        '\'#uname eq {{ constraint.node }}
      {% endif %}
      {% for option in constraint.options | d([]) if option.name != 'score' %}
        {{ option.name | quote }}={{ option.value | quote }}
      {% endfor %}
    # ERROR and "Do you still want to commit (y/n)?" trigger response "n".
    responses:
      ".*ERROR.*": "n"
      ".*y/n*": "n"
  check_mode: false
  changed_when: not ansible_check_mode
  ignore_errors: true
  register: __ha_cluster_crmsh_output

- name: Display crm command error details
  ansible.builtin.fail:
    msg: "{{ __ha_cluster_crmsh_output.stdout_lines }}"
  when:
    - __ha_cluster_crmsh_output is defined
    - __ha_cluster_crmsh_output.rc != 0
