---
- name: Set mesh configuration
  vars:
    conn_policies: "{{ conn.policies | selectattr('cidr', 'match', '^default$') | map(attribute='policy') | join(',') }}"
    pol_default: "{{ vpn_default_policy if conn_policies | length == 0 else conn_policies }}"
  block:
    - name: Set current IP fact for each host
      set_fact:
        __vpn_current_ip: "{{ ansible_default_ipv4.address | d(ansible_default_ipv6.address) }}"

    - name: Set IP with prefix register
      shell: |-
        set -euo pipefail
        ip addr show | grep {{ __vpn_current_ip }} | awk '{print $2}'
      register: __vpn_ip_with_prefix_register
      changed_when: false

    - name: Set net CIDR fact
      set_fact:
        __vpn_current_subnet: "{{ __vpn_ip_with_prefix_register.stdout | vpn_ipaddr('subnet') }}"

    - name: Set policies fact
      set_fact:
        __vpn_policies: "{{ conn.policies | rejectattr('cidr', 'match', '^default$') | list }}"

    - name: Apply the default policy as needed
      set_fact:
        __new_vpn_policies: "{{ __new_vpn_policies | d([]) + new_policy_or_empty | list }}"
      delegate_to: localhost
      run_once: true
      loop: "{{ the_product }}"
      vars:
        the_product: "{{ policy_cidrs | product(node_ips_subnets) | list }}"
        in_subnet: "{{ item.1.0 | vpn_ipaddr(item.0) | vpn_ipaddr('bool') }}"
        new_policy:
          policy: "{{ pol_default }}"
          cidr: "{{ item.1.1 }}"
        new_policy_or_empty: "{{ [new_policy] if not in_subnet else [] }}"
        policy_cidrs: "{{ __vpn_policies | map(attribute='cidr') | list }}"
        node_ips: "{{ ansible_play_hosts | map('extract', hostvars, '__vpn_current_ip') | list }}"
        node_subnets: "{{ ansible_play_hosts | map('extract', hostvars, '__vpn_current_subnet') | list }}"
        node_ips_subnets: "{{ node_ips | zip(node_subnets) | list }}"

    - name: Reset policies to include the added ones above
      set_fact:
        __vpn_policies: "{{ __vpn_policies + __new_vpn_policies | unique | list }}"

    - name: Write tunnel policies for each network
      template:
        src: 'policy.j2'
        dest: "/etc/ipsec.d/policies/{{ item }}"
        mode: '0644'
      loop: "{{ __vpn_policies | map(attribute='policy') | unique | list }}"
      notify:
        - __vpn_handler_enable_start_vpn
        - __vpn_handler_init_mesh_conns

    - name: Deploy opportunistic configuration to each node
      template:
        src: "{{ vpn_provider }}-mesh.conf.j2"
        dest: "/etc/ipsec.d/mesh.conf"
        mode: '0644'
      notify:
        - __vpn_handler_enable_start_vpn
        - __vpn_handler_init_mesh_conns
