---
- name: Attempt to connect on non-standard port first
  wait_for:
    host: "{{ ansible_host }}"
    port: "{{ ansible_port }}"
    timeout: 3
  ignore_errors: true
  register: ssh_check_test
  delegate_to: localhost
  when: ansible_connection != 'local'

- name: Revert to standard port 22 for SSH if the "secure" port has not been configured yet
  set_fact:
    ansible_port: "22"
  when:
    - ansible_connection != 'local'
    - ssh_check_test.failed is defined
    - ssh_check_test.failed

- name: Ensure python-netaddr is installed on Ansible controller host
  become: false
  pip:
    name: netaddr
  delegate_to: localhost

- name: Determine facts based on the host's ID
  set_fact:
    fqdn: "{{ hosts[host_id].hosts.split()[-1] }}"
    hostname: "{{ hosts[host_id].hostname }}"
    host_list: "{{ hosts | list }}"
    ip_address: "{{ hosts[host_id].ip_address }}"
    nginx_sites: "{{ apps }}"

- name: Determine the VLAN (set to cloud if none match)
  vars:
    netmask: "24"
  block:
    - name: Set value for the variable vlan_ip
      set_fact:
        vlan_ip: "{{ hosts
          | map('extract', hosts)
          | selectattr('hostname', 'defined')
          | selectattr('hostname', 'equalto', hostname)
          | map(attribute='ip_address')
          | flatten }}"
    - name: Set value for the variable cidr
      set_fact:
        cidr: "{{ (vlan_ip[0] + '/' + netmask) | ipaddr('network/prefix') }}"
      when: vlan_ip
    - name: Set value for the variable vlan
      set_fact:
        vlan: "{{ item.key | default('cloud') }}"
      loop: "{{ lookup('dict', lan_network) }}"
      when:
        - vlan_ip
        - cidr in item.value
  always:
    - name: Set value for the variable vlan
      set_fact:
        vlan: cloud
      when: not vlan_ip

- name: Set miscellaneous facts
  set_fact:
    docker_tls_fqdn: "{{ fqdn }}"
    #   kibana_enrollment_id: "{{ vlan }}"

# See https://stackoverflow.com/questions/66897203/converting-data-structure-in-ansible
- name: Set app_host_map fact
  set_fact:
    app_host_map: "{{ new_app_map | default({}) | combine({item.1: item.0.key}) }}"
  with_subelements:
    - "{{ app_map | dict2items }}"
    - value

- name: Debug new_app_map
  debug:
    msg: "{{ app_host_map }}"

- name: Set the appropriate netdata room
  set_fact:
    netdata_room: "{{ netdata_rooms[vlan] }}" # TODO: Improve this method so that we can segment different cloud providers
  when:
    - netdata_rooms is defined

- name: Set cloud VLAN facts
  set_fact:
    add_hosts: false
    dns_provider: 1.1.1.1#cloudflare-dns.com
    dns_fallback_provider: 1.0.0.1#cloudflare-dns.com
    https_repository_prefix: https://
  when: vlan == 'cloud'

- name: Check if ubuntu user is present
  block:
    - name: Check if connection is possible
      expect:
        command: "ssh -o PubkeyAuthentication=no -o StrictHostKeyChecking=no ubuntu@{{ ansible_host }} -p {{ ansible_port }}"
        timeout: 2
        responses:
          (.*)password(.*):
            - "{{ ansible_password }}"      # Fit the password
            - "\x03"          # Ctrl-C
          (.*)\$(.*): "exit"  # Fit the prompt
      register: can_connect_as_ubuntu
      connection: local
      ignore_errors: true
      changed_when: false
    - name: Save the name of the user to be created
      set_fact:
        ansible_user_new: "{{ ansible_user }}"
      when: not can_connect_as_ubuntu.failed
    - name: Set the value of ansible_user
      set_fact:
        ansible_user: "{{ ansible_user_remove | default('ubuntu') if not can_connect_as_ubuntu.failed else ansible_user }}"
  when: replace_ubuntu_user_with_ansible_user is defined and replace_ubuntu_user_with_ansible_user | bool

- name: Ensure user 'ubuntu' is removed if present
  become: true
  block:
    - name: "Create new user account for {{ ansible_user_new }}"
      become_user: root
      user:
        name: "{{ ansible_user_new }}"
        state: present
        password: "{{ ansible_password | password_hash('sha512', password_salt) }}"
    - name: "Add the user {{ ansible_user_new }} to passwordless sudoers"
      lineinfile:
        dest: /etc/sudoers
        regexp: "^{{ ansible_user_new }}"
        line: "{{ ansible_user_new }} ALL=(ALL) NOPASSWD: ALL"
        state: present
        validate: "visudo -cf %s"
        mode: 0644
    - name: Set fact to use the newly created user for connections
      set_fact:
        ansible_user: "{{ ansible_user_new }}"
    - wait_for_connection:
        timeout: 10
    - name: Kill processes owned by ubuntu user # noqa 301
      command: "pkill -u ubuntu"
      ignore_errors: true
    - name: Remove old user
      user:
        name: ubuntu
        state: absent
        remove: true
  when:
    - replace_ubuntu_user_with_ansible_user is defined and replace_ubuntu_user_with_ansible_user | bool
    - can_connect_as_ubuntu is defined and not can_connect_as_ubuntu.failed
