---
- name: "BASE-SYSTEM: Common Setup for All Nodes"
  hosts: all
  gather_facts: yes
  vars_files:
    - "group_vars/all/generated_vars.stress.yml" # Assumes generate-inventory.py was run with cluster.stress.yml
    - "group_vars/all/vault.yml"
  pre_tasks:
    - name: Announce base system setup
      ansible.builtin.debug:
        msg: "Starting base system setup on {{ inventory_hostname }}"

  tasks:
    # 1. Install System Essentials
    - name: Install NTP for time synchronization
      ansible.builtin.apt:
        name: ntp
        state: present
      become: yes

    - name: Ensure NTP service is started and enabled
      ansible.builtin.service:
        name: ntp
        state: started
        enabled: yes
      become: yes

    - name: Install pipx
      ansible.builtin.apt:
        name: pipx
        state: present
      become: yes

    - name: Install Glances for system monitoring
      ansible.builtin.command: pipx install glances[all]
      args:
        creates: "{{ ansible_env.HOME }}/.local/bin/glances"
      become: yes
      become_user: "{{ ansible_user }}"

    - name: Install base system packages for tools
      ansible.builtin.apt:
        name:
          - unzip
          - wget
          - xz-utils
          - build-essential
          - python3-pip
        state: present
        update_cache: yes
      become: yes

    # 2. Secure the Host
    - name: Copy secure sshd_config
      ansible.builtin.copy:
        src: "configs/etc/ssh/sshd_config"
        dest: "/etc/ssh/sshd_config"
        owner: root
        group: root
        mode: '0644'
      become: yes
      notify: Restart sshd

    - name: Include Fail2ban role
      ansible.builtin.include_role:
        name: fail2ban

    # 3. Manage Hostname Resolution
    - name: Update /etc/hosts file for cluster name resolution
      ansible.builtin.lineinfile:
        path: /etc/hosts
        regexp: '.* {{ item }}$'
        line: "{{ hostvars[item].ansible_host }} {{ item }}"
        state: present
      loop: "{{ groups['all'] }}"
      become: yes

    # 4. Install Docker
    - name: Install Docker
      block:
        - name: Check if Docker is already installed
          ansible.builtin.stat:
            path: /usr/bin/docker
          register: docker_binary

        - name: Install Docker if not present
          block:
            - name: Add Docker's official GPG key
              ansible.builtin.apt_key:
                url: https://download.docker.com/linux/ubuntu/gpg
                state: present

            - name: Set up the Docker repository
              ansible.builtin.apt_repository:
                repo: "deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ ansible_lsb.codename }} stable"
                state: present

            - name: Install prerequisites for Docker
              ansible.builtin.apt:
                name:
                  - apt-transport-https
                  - ca-certificates
                  - curl
                  - software-properties-common
                state: present
                update_cache: yes

            - name: Install Docker Engine and Docker Compose
              ansible.builtin.apt:
                name:
                  - docker-ce
                  - docker-ce-cli
                  - containerd.io
                  - docker-compose-plugin
                  - python3-docker
                state: present
                update_cache: yes
          when: not docker_binary.stat.exists
      become: yes

    # 5. Configure Docker Service & User
    - name: Ensure Docker service is started and enabled
      ansible.builtin.service:
        name: docker
        state: started
        enabled: yes
      become: yes

    - name: Add deploy user to the docker group
      ansible.builtin.user:
        name: "{{ ansible_user }}"
        groups: docker
        append: yes
      become: yes

    - name: Reset SSH connection to apply group changes
      ansible.builtin.meta: reset_connection

    # 6. Create Shared Docker Network
    - name: Ensure shared Docker network exists
      community.docker.docker_network:
        name: "{{ docker_network_name }}"
        driver: bridge
      become: yes

  handlers:
    - name: Restart sshd
      ansible.builtin.service:
        name: ssh
        state: restarted
      become: yes
