---
# Set start timestamp before deploying workloads
- name: Set role variables
  set_fact:
    cloud_provider_env:
      AWS_ACCESS_KEY_ID: "{{ AWS_ACCESS_KEY_ID | default(omit) }}"
      AWS_SECRET_ACCESS_KEY: "{{ AWS_SECRET_ACCESS_KEY | default(omit) }}"
      AWS_DEFAULT_REGION: "{{ 'us-east-1' if cloud_provider == 'eks' else omit }}"

# Run debug tasks before starting the experiment
- name: Run debug tasks
  include_tasks: debug.yml

- name: Set experiment start time
  set_fact:
    experiment_start_time: "{{ lookup('pipe', 'date --utc +%Y-%m-%dT%H:%M:%SZ') }}"

# Deploy homogeneous workload scenario
- name: Deploy homogeneous workload
  block:
    - name: Create namespace for homogeneous workload in each cluster
      kubernetes.core.k8s:
        name: "{{ homogeneous_workload.namespace }}"
        api_version: v1
        kind: Namespace
        state: present
      environment: "{{ cloud_provider_env | combine({'KUBECONFIG': lookup('vars', 'KUBECONFIG_' ~ cloud_provider | upper ~ '_' ~ item)}) }}"
      loop:
        - KARPENTER
        - CAS

    - name: Deploy homogeneous workload to clusters
      kubernetes.core.k8s:
        definition:
          apiVersion: apps/v1
          kind: Deployment
          metadata:
            name: "homogeneous-workload-{{ item | lower }}"
            namespace: "{{ homogeneous_workload.namespace }}"
          spec:
            replicas: 40
            selector:
              matchLabels:
                app: "homogeneous-workload-{{ item | lower }}"
            template:
              metadata:
                labels:
                  app: "homogeneous-workload-{{ item | lower }}"
              spec:
                containers:
                - name: workload-container
                  image: "{{ homogeneous_workload.container.image }}"
                  resources:
                    requests:
                      cpu: "{{ homogeneous_workload.container.resources.cpu }}"
                      memory: "{{ homogeneous_workload.container.resources.memory_request }}"
                    limits:
                      cpu: "{{ homogeneous_workload.container.resources.cpu }}"
                      memory: "{{ homogeneous_workload.container.resources.memory_limit }}"
                  command: ["stress"]
                  args: "{{ homogeneous_workload.container.args }}"
      environment: "{{ cloud_provider_env | combine({'KUBECONFIG': lookup('vars', 'KUBECONFIG_' ~ cloud_provider | upper ~ '_' ~ item)}) }}"
      loop:
        - KARPENTER
        - CAS
  when: workload_scenario == 'homogeneous'

# Deploy heterogeneous workload scenario
- name: Deploy heterogeneous workload
  block:
    - name: Create namespace for heterogeneous workload in each cluster
      kubernetes.core.k8s:
        name: "{{ heterogeneous_workload.namespace }}"
        api_version: v1
        kind: Namespace
        state: present
      environment: "{{ cloud_provider_env | combine({'KUBECONFIG': lookup('vars', 'KUBECONFIG_' ~ cloud_provider | upper ~ '_' ~ item)}) }}"
      loop:
        - KARPENTER
        - CAS

    - name: Deploy CPU intensive workloads to clusters
      include_tasks: deploy_cpu_workload.yml
      loop:
        - KARPENTER
        - CAS
      loop_control:
        loop_var: cluster_type
  when: workload_scenario == 'heterogeneous'

# Wait for workloads to stabilize
- name: Wait for initial workloads to stabilize
  ansible.builtin.wait_for:
    timeout: 600

# Set namespace state to match deployment state
- name: Set homogeneous workload namespace state
  kubernetes.core.k8s:
    name: "{{ homogeneous_workload.namespace }}"
    api_version: v1
    kind: Namespace
    state: absent
  environment: "{{ cloud_provider_env | combine({'KUBECONFIG': lookup('vars', 'KUBECONFIG_' ~ cloud_provider | upper ~ '_' ~ item)}) }}"
  loop:
    - KARPENTER
    - CAS
  when: workload_scenario == 'homogeneous'

- name: Set heterogeneous workload namespace state
  kubernetes.core.k8s:
    name: "{{ heterogeneous_workload.namespace }}"
    api_version: v1
    kind: Namespace
    state: absent
  environment: "{{ cloud_provider_env | combine({'KUBECONFIG': lookup('vars', 'KUBECONFIG_' ~ cloud_provider | upper ~ '_' ~ item)}) }}"
  loop:
    - KARPENTER
    - CAS
  when: workload_scenario == 'heterogeneous'

# Wait for scale down after namespace state change
- name: Wait for scale down after namespace state change
  ansible.builtin.wait_for:
    timeout: 600

# Set end timestamp after workload stabilization
- name: Set experiment end time
  set_fact:
    experiment_end_time: "{{ lookup('pipe', 'date --utc +%Y-%m-%dT%H:%M:%SZ') }}"

- name: Create output directories
  file:
    path: "{{ playbook_dir }}/experiment-data/{{ cloud_provider }}/{{ item }}/{{ workload_scenario }}"
    state: directory
  loop:
    - karpenter
    - cas

# Collect billing metrics
- name: Collect billing metrics
  block:
    - name: Retrieve AWS billing data
      ansible.builtin.command:
        cmd: python3 files/scripts/fetch_billing_data_aws.py --tag_key 'tag' --tag_value '{{ item }}-{{ tag_uuid }}' --access_key '{{ AWS_ACCESS_KEY_ID }}' --secret_key '{{ AWS_SECRET_ACCESS_KEY }}' --output_file '{{ playbook_dir }}/experiment-data/{{ cloud_provider }}/{{ item }}/{{ workload_scenario }}/aws_billing_metrics_{{ item }}.json'
      loop:
        - karpenter
        - cas
      when: cloud_provider == 'eks'

    - name: Retrieve IBM billing data
      ansible.builtin.command:
        cmd: python3 files/scripts/fetch_billing_data_ibm.py --tag_value '{{ item }}-{{ tag_uuid }}' --api_key '{{ IBM_CLOUD_TOKEN }}' --output_file '{{ playbook_dir }}/experiment-data/{{ cloud_provider }}/{{ item }}/{{ workload_scenario }}/ibm_billing_metrics_{{ item }}.json' --account_id '{{ IBM_CLOUD_ACCOUT_ID }}'
      loop:
        - karpenter
        - cas
      when: cloud_provider == 'iks'

# Collect prometheus metrics
- name: Collect prometheus metrics
  include_tasks: collect_metrics.yml
  vars:
    start_time: "{{ experiment_start_time }}"
    end_time: "{{ experiment_end_time }}"

# Run debug tasks after running the experiment
- name: Run debug tasks
  include_tasks: debug.yml
