# Create the local k3d simulation cluster — an executable miniature of the
# ground segment (k3s) from docs/06. Terraform then owns the workloads.
---
- name: Simulation cluster (k3d)
  hosts: localhost
  connection: local
  gather_facts: false
  vars:
    cluster_name: swarm-sim
    repo_root: "{{ playbook_dir }}/../.."
    data_dir: "{{ lookup('env', 'SWARM_SIM_DATA') | default(repo_root + '/var/t1', true) }}"
    warehouse_dir: "{{ lookup('env', 'SWARM_WAREHOUSE_DATA') | default(repo_root + '/var/t3', true) }}"
    api_port: 6560
    # Host ports for services exposed by the Terraform modules (NodePorts)
    port_explorer: 30088
    port_grafana: 30300
    port_prometheus: 30990
    port_warehouse_explorer: 30089
    port_minio_console: 30901
    simulator_image: swarm-house/simulator:dev

  tasks:
    - name: Check k3d is installed
      ansible.builtin.command: k3d version
      changed_when: false

    - name: Create shared data directory (the pods' /data lake)
      ansible.builtin.file:
        path: "{{ data_dir }}"
        state: directory
        mode: "0777"

    - name: Create warehouse directory (T3 host path inside the k3d node)
      ansible.builtin.file:
        path: "{{ warehouse_dir }}"
        state: directory
        mode: "0777"

    - name: List existing clusters
      ansible.builtin.command: k3d cluster list -o json
      register: clusters
      changed_when: false

    - name: Create cluster {{ cluster_name }}
      ansible.builtin.command: >-
        k3d cluster create {{ cluster_name }}
        --api-port {{ api_port }}
        --servers 1 --agents 0
        --volume {{ data_dir }}:/data@server:0
        --volume {{ warehouse_dir }}:/warehouse@server:0
        --port {{ port_explorer }}:{{ port_explorer }}@server:0
        --port {{ port_grafana }}:{{ port_grafana }}@server:0
        --port {{ port_prometheus }}:{{ port_prometheus }}@server:0
        --port {{ port_warehouse_explorer }}:{{ port_warehouse_explorer }}@server:0
        --port {{ port_minio_console }}:{{ port_minio_console }}@server:0
        --k3s-arg "--disable=traefik@server:0"
        --wait
      when: clusters.stdout | from_json | selectattr('name', 'equalto', cluster_name) | list | length == 0

    - name: Build simulator image
      ansible.builtin.command:
        cmd: docker build -t {{ simulator_image }} .
        chdir: "{{ playbook_dir }}/../../simulator"
      register: build
      changed_when: "'Using cache' not in build.stderr"

    - name: Import simulator image into the cluster
      ansible.builtin.command: k3d image import {{ simulator_image }} -c {{ cluster_name }}
      changed_when: true

    - name: Merge k3d kubeconfig into the default context
      ansible.builtin.command: k3d kubeconfig merge {{ cluster_name }} --kubeconfig-merge-default
      changed_when: false

    - name: Check whether Flux CLI is available
      ansible.builtin.command: flux version --client
      register: flux_cli
      changed_when: false
      failed_when: false

    - name: Install Flux CLI (local user bin)
      when: flux_cli.rc != 0
      block:
        - name: Download Flux release archive
          ansible.builtin.get_url:
            url: https://github.com/fluxcd/flux2/releases/download/v2.4.0/flux_2.4.0_linux_amd64.tar.gz
            dest: /tmp/flux.tar.gz
            mode: "0644"
        - name: Extract flux binary
          ansible.builtin.unarchive:
            src: /tmp/flux.tar.gz
            dest: "{{ lookup('env', 'HOME') }}/.local/bin"
            remote_src: true
            include:
              - flux
            extra_opts:
              - --no-same-owner
          ignore_errors: true
        - name: Ensure flux is executable
          ansible.builtin.file:
            path: "{{ lookup('env', 'HOME') }}/.local/bin/flux"
            mode: "0755"
            state: file

    - name: Install Flux controllers into the cluster
      ansible.builtin.command: flux install --namespace=flux-system --components=source-controller,kustomize-controller
      environment:
        PATH: "{{ lookup('env', 'HOME') }}/.local/bin:{{ lookup('env', 'PATH') }}"
        KUBECONFIG: "{{ lookup('env', 'HOME') }}/.kube/config"
      register: flux_install
      changed_when: "'installed' in (flux_install.stdout | default(''))"

    - name: Apply Flux GitOps CRs (GitRepository + Kustomization)
      ansible.builtin.command: kubectl apply -k {{ repo_root }}/infra/gitops/flux
      changed_when: true

    - name: Seed ground GitOps resources locally (works before first git push)
      ansible.builtin.command: kubectl apply -k {{ repo_root }}/infra/gitops/ground
      changed_when: true

    - name: Show kubeconfig hint
      ansible.builtin.debug:
        msg: >-
          Cluster ready. Workloads: cd ../terraform/sim-env && terraform init && terraform apply.
          kubeconfig: k3d kubeconfig get {{ cluster_name }}
