---
# AWS Cleanup Playbook - Comprehensive version with robust VPC removal
- name: Clean up AWS resources
  hosts: localhost
  gather_facts: false
  connection: local
  vars_files:
    - vars.yaml
  vars:
    aws_region: "{{ aws_region | default(aws_region_choices | random) }}"
    confirm_cleanup: "{{ confirm_cleanup | default(true) }}"
    deployment_id: "{{ deployment_id | default('') }}"
    redirector_name: "{{ redirector_name | default('r-' + deployment_id) }}"
    c2_name: "{{ c2_name | default('s-' + deployment_id) }}"
    tracker_name: "{{ tracker_name | default('t-' + deployment_id) }}"
    cleanup_summary: {}
    
  tasks:
    # Confirmation step (if enabled)
    - name: Confirm cleanup
      pause:
        prompt: "Are you sure you want to delete all AWS resources for deployment ID {{ deployment_id }}? This action cannot be undone. Type 'yes' to confirm"
      register: cleanup_confirmation
      when: confirm_cleanup | bool
    
    - name: Check confirmation
      assert:
        that:
          - cleanup_confirmation.user_input | default('yes') == 'yes'
        fail_msg: "Cleanup cancelled by user"
      when: confirm_cleanup | bool
    
    # STEP 1: Find all instances by deployment ID
    - name: Find all EC2 instances for this deployment
      amazon.aws.ec2_instance_info:
        region: "{{ aws_region }}"
        filters:
          "tag:deployment_id": "{{ deployment_id }}"
      register: deployment_instances
      
    - name: Set fact for instances found
      set_fact:
        cleanup_summary: "{{ cleanup_summary | combine({'instances_found': deployment_instances.instances | length}) }}"
      
    # STEP 2: Terminate all instances with proper tagging
    - name: Terminate all instances for this deployment
      amazon.aws.ec2_instance:
        instance_ids: "{{ item.instance_id }}"
        region: "{{ aws_region }}"
        state: absent
      loop: "{{ deployment_instances.instances }}"
      register: terminated_instances
      when: deployment_instances.instances | length > 0
      
    - name: Wait for instances to be terminated
      pause:
        seconds: 30
      when: deployment_instances.instances | length > 0
    
    # STEP 3: Find all security groups by deployment ID
    - name: Find all security groups for this deployment
      amazon.aws.ec2_security_group_info:
        region: "{{ aws_region }}"
        filters:
          "tag:deployment_id": "{{ deployment_id }}"
      register: deployment_sgs
      
    # Also find SGs by name pattern
    - name: Find security groups by name pattern
      amazon.aws.ec2_security_group_info:
        region: "{{ aws_region }}"
      register: all_sgs
        
    - name: Filter SGs by name pattern
      set_fact:
        named_sgs: "{{ all_sgs.security_groups | selectattr('group_name', 'search', redirector_name + '-sg|' + c2_name + '-sg') | list }}"
      
    - name: Combine all security groups to delete
      set_fact:
        all_sgs_to_delete: "{{ deployment_sgs.security_groups + named_sgs }}"
        cleanup_summary: "{{ cleanup_summary | combine({'security_groups_found': (deployment_sgs.security_groups + named_sgs) | length}) }}"
    
    # STEP 4: Delete all security groups
    - name: Delete security groups
      amazon.aws.ec2_security_group:
        group_id: "{{ item.group_id }}"
        region: "{{ aws_region }}"
        state: absent
      loop: "{{ all_sgs_to_delete }}"
      when: all_sgs_to_delete | length > 0
      ignore_errors: yes
      register: deleted_sgs
    
    # STEP 5: Find and delete all ENIs
    - name: Find network interfaces by tag
      amazon.aws.ec2_eni_info:
        region: "{{ aws_region }}"
        filters:
          "tag:deployment_id": "{{ deployment_id }}"
      register: deployment_enis
      
    - name: Delete ENIs
      amazon.aws.ec2_eni:
        region: "{{ aws_region }}"
        eni_id: "{{ item.id }}"
        state: absent
        force_detach: true
      loop: "{{ deployment_enis.network_interfaces }}"
      ignore_errors: yes
      register: deleted_enis
      when: deployment_enis.network_interfaces | length > 0
      
    - name: Set ENIs count in summary
      set_fact:
        cleanup_summary: "{{ cleanup_summary | combine({'enis_found': deployment_enis.network_interfaces | length}) }}"
      
    # STEP 6: Find all VPCs by deployment ID
    - name: Find all VPCs for this deployment
      amazon.aws.ec2_vpc_net_info:
        region: "{{ aws_region }}"
        filters:
          "tag:deployment_id": "{{ deployment_id }}"
      register: deployment_vpcs
    
    # STEP 7: Find VPCs by name pattern as fallback
    - name: Find all VPCs by name pattern
      amazon.aws.ec2_vpc_net_info:
        region: "{{ aws_region }}"
      register: all_vpcs
    
    - name: Filter VPCs by name pattern
      set_fact:
        named_vpcs: "{{ all_vpcs.vpcs | selectattr('tags', 'defined') | selectattr('tags.Name', 'defined') | selectattr('tags.Name', 'search', redirector_name + '-vpc|' + c2_name + '-vpc') | list }}"
    
    - name: Combine all VPCs to delete
      set_fact:
        all_vpcs_to_delete: "{{ deployment_vpcs.vpcs + named_vpcs | unique(attribute='vpc_id') }}"
        cleanup_summary: "{{ cleanup_summary | combine({'vpcs_found': (deployment_vpcs.vpcs + named_vpcs | unique(attribute='vpc_id')) | length}) }}"

    # STEP 8: Find and delete NAT Gateways for each VPC separately
    - name: Find NAT gateways in each VPC
      amazon.aws.ec2_vpc_nat_gateway_info:
        region: "{{ aws_region }}"
        filters:
          vpc-id: "{{ item.vpc_id }}"
      register: natgw_results
      loop: "{{ all_vpcs_to_delete }}"
      when: all_vpcs_to_delete | length > 0
      
    - name: Delete NAT gateways
      amazon.aws.ec2_vpc_nat_gateway:
        region: "{{ aws_region }}"
        nat_gateway_id: "{{ item.1.nat_gateway_id }}"
        state: absent
        release_eip: true
      loop: "{{ natgw_results.results | default([]) | selectattr('skipped', 'undefined') | selectattr('nat_gateways', 'defined') | subelements('nat_gateways') }}"
      ignore_errors: yes
      register: deleted_natgws
      when: natgw_results.results is defined

    - name: Wait after NAT deletion
      pause:
        seconds: 15
      when: deleted_natgws.results is defined and deleted_natgws.results | length > 0

    # STEP 9: Find and delete Internet Gateways
    - name: Find internet gateways for each VPC
      amazon.aws.ec2_vpc_igw_info:
        region: "{{ aws_region }}"
        filters:
          attachment.vpc-id: "{{ item.vpc_id }}"
      register: igw_results
      loop: "{{ all_vpcs_to_delete }}"
      when: all_vpcs_to_delete | length > 0
      
    - name: Detach and delete internet gateways
      # Fix the reference to attachment - should use item.1.attachments or similar
      ec2_vpc_igw:
        vpc_id: "{{ item.1.attachments[0].vpc_id }}"  # Fix this line
        state: absent
        region: "{{ aws_region }}"
      with_together: "{{ find_igws.results|default([]) }}"
      register: deleted_igws
      ignore_errors: yes
      
    - name: Wait after IGW deletion
      pause:
        seconds: 15
      when: deleted_igws.results is defined and deleted_igws.results | length > 0

    # STEP 10: Find and delete Route Tables
    - name: Find route tables for each VPC
      amazon.aws.ec2_vpc_route_table_info:
        region: "{{ aws_region }}"
        filters:
          vpc-id: "{{ item.vpc_id }}"
      register: rtb_results
      loop: "{{ all_vpcs_to_delete }}"
      when: all_vpcs_to_delete | length > 0
      
    - name: Delete non-main route tables
      amazon.aws.ec2_vpc_route_table:
        region: "{{ aws_region }}"
        route_table_id: "{{ item.1.id }}"
        lookup: id
        state: absent
      loop: "{{ rtb_results.results | default([]) | selectattr('skipped', 'undefined') | selectattr('route_tables', 'defined') | subelements('route_tables') }}"
      when: not item.1.associations[0].main | default(false)
      ignore_errors: yes
      register: deleted_rtbs

    # Add this after your existing route table deletion
    - name: Delete main route tables with AWS CLI
      shell: |
        for rtb in $(aws ec2 describe-route-tables --region {{ aws_region }} --filters "Name=vpc-id,Values={{ item.vpc_id }}" --query 'RouteTables[?Associations[?Main==`true`]].RouteTableId' --output text); do
          aws ec2 delete-route --route-table-id $rtb --destination-cidr-block 0.0.0.0/0 --region {{ aws_region }} || true
        done
      environment:
        AWS_ACCESS_KEY_ID: "{{ aws_access_key }}"
        AWS_SECRET_ACCESS_KEY: "{{ aws_secret_key }}"
      loop: "{{ all_vpcs_to_delete }}"
      ignore_errors: yes
      when: all_vpcs_to_delete | length > 0

    # STEP 11: Find and delete Subnets
    - name: Find subnets for each VPC
      ec2_vpc_subnet_info:
        filters:
          vpc-id: "{{ item.vpc_id }}"  # Fix this line, should be vpc_id not vpc_idvpc
        region: "{{ aws_region }}"
      with_items: "{{ all_vpcs_to_delete }}"
      register: find_subnets
      
    - name: Delete subnets
      amazon.aws.ec2_vpc_subnet:
        region: "{{ aws_region }}"
        vpc_id: "{{ item.1.vpc_id }}"
        cidr: "{{ item.1.cidr_block }}"
        state: absent
      loop: "{{ subnet_results.results | default([]) | selectattr('skipped', 'undefined') | selectattr('subnets', 'defined') | subelements('subnets') }}"
      ignore_errors: yes
      register: deleted_subnets
      when: subnet_results.results is defined
     
    # STEP 12: Find and delete VPC Endpoints
    - name: Find VPC endpoints for each VPC
      amazon.aws.ec2_vpc_endpoint_info:
        region: "{{ aws_region }}"
        filters:
          vpc-id: "{{ item.vpc_id }}"
      register: endpoint_results
      loop: "{{ all_vpcs_to_delete }}"
      when: all_vpcs_to_delete | length > 0
      
    - name: Delete VPC endpoints
      amazon.aws.ec2_vpc_endpoint:
        region: "{{ aws_region }}"
        vpc_endpoint_id: "{{ item.1.vpc_endpoint_id }}"
        state: absent
      loop: "{{ endpoint_results.results | default([]) | selectattr('skipped', 'undefined') | selectattr('vpc_endpoints', 'defined') | subelements('vpc_endpoints') }}"
      ignore_errors: yes
      register: deleted_endpoints
      when: endpoint_results.results is defined

    # Add before STEP 13
    - name: Check for remaining VPC dependencies
      shell: |
        aws ec2 describe-network-interfaces --region {{ aws_region }} --filters "Name=vpc-id,Values={{ item.vpc_id }}" --output json
      environment:
        AWS_ACCESS_KEY_ID: "{{ aws_access_key }}"
        AWS_SECRET_ACCESS_KEY: "{{ aws_secret_key }}"
      register: remaining_deps
      loop: "{{ all_vpcs_to_delete }}"
      when: all_vpcs_to_delete | length > 0
      
    - name: Display any remaining dependencies
      debug:
        msg: "VPC {{ item.item.vpc_id }} still has dependencies that need to be removed"
      loop: "{{ remaining_deps.results }}"
      when: item.stdout | from_json | json_query('NetworkInterfaces') | length > 0

    # Add this before the force delete of network interfaces
    - name: Detach remaining network interfaces
      shell: |
        aws ec2 detach-network-interface --attachment-id $(aws ec2 describe-network-interfaces --network-interface-ids {{ item.1 }} --query 'NetworkInterfaces[0].Attachment.AttachmentId' --output text) --region {{ aws_region }} --force
      environment:
        AWS_ACCESS_KEY_ID: "{{ aws_access_key }}"
        AWS_SECRET_ACCESS_KEY: "{{ aws_secret_key }}"
      loop: "{{ remaining_deps.results | selectattr('stdout', 'defined') | 
                map('attr', 'stdout') | map('from_json') | 
                map('json_query', 'NetworkInterfaces[?Status==`in-use`].NetworkInterfaceId') | 
                zip(remaining_deps.results | map('attr', 'item')) | list }}"
      ignore_errors: yes
      when: item.0 | length > 0
      
    - name: Force delete any remaining network interfaces
      shell: |
        aws ec2 delete-network-interface --network-interface-id {{ item.1 }} --region {{ aws_region }}
      environment:
        AWS_ACCESS_KEY_ID: "{{ aws_access_key }}"
        AWS_SECRET_ACCESS_KEY: "{{ aws_secret_key }}"
      loop: "{{ remaining_deps.results | selectattr('stdout', 'defined') | 
                map('attr', 'stdout') | map('from_json') | 
                map('json_query', 'NetworkInterfaces[].NetworkInterfaceId') | 
                zip(remaining_deps.results | map('attr', 'item')) | list }}"
      ignore_errors: yes
      when: item.0 | length > 0

    # STEP 13: Final VPC deletion with multiple retries
    - name: Wait for all dependencies to clear
      pause:
        seconds: 20
      when: all_vpcs_to_delete | length > 0
      
    # First attempt with normal module - with error display
    - name: Delete all VPCs (first attempt)
      amazon.aws.ec2_vpc_net:
        vpc_id: "{{ item.vpc_id }}"
        region: "{{ aws_region }}"
        state: absent
      loop: "{{ all_vpcs_to_delete }}"
      register: vpc_deletion
      when: all_vpcs_to_delete | length > 0
      ignore_errors: yes
      
    - name: Display VPC deletion errors
      debug:
        msg: "Failed to delete VPC {{ item.item.vpc_id }}: {{ item.msg }}"
      loop: "{{ vpc_deletion.results | default([]) }}"
      when: item.failed is defined and item.failed

    # Direct API call for any VPCs that failed
    - name: Find which VPCs still exist
      amazon.aws.ec2_vpc_net_info:
        region: "{{ aws_region }}"
        vpc_ids: "{{ all_vpcs_to_delete | map(attribute='vpc_id') | list }}"
      register: remaining_vpcs
      when: all_vpcs_to_delete | length > 0
      
    # Forcibly delete with direct AWS CLI command
    - name: Force delete remaining VPCs with CLI
      shell: |
        aws ec2 delete-vpc --vpc-id {{ item.vpc_id }} --region {{ aws_region }}
      environment:
        AWS_ACCESS_KEY_ID: "{{ aws_access_key }}"
        AWS_SECRET_ACCESS_KEY: "{{ aws_secret_key }}"
      loop: "{{ remaining_vpcs.vpcs }}" 
      ignore_errors: yes
      when: remaining_vpcs is defined and remaining_vpcs.vpcs | length > 0
      register: force_vpc_delete

    # Add after the VPC deletion attempts - more aggressive approach
    - name: Force delete remaining VPCs with AWS CLI and debug output
      shell: |
        aws ec2 delete-vpc --vpc-id {{ item.vpc_id }} --region {{ aws_region }} 2>&1 || echo "Failed with: $?"
      environment:
        AWS_ACCESS_KEY_ID: "{{ aws_access_key }}"
        AWS_SECRET_ACCESS_KEY: "{{ aws_secret_key }}"
      loop: "{{ remaining_vpcs.vpcs }}" 
      register: force_vpc_delete_debug
      when: remaining_vpcs is defined and remaining_vpcs.vpcs | length > 0
      
    - name: Display debug output from force delete
      debug:
        msg: "{{ item.stdout }}"
      loop: "{{ force_vpc_delete_debug.results | default([]) }}"
      when: item.stdout is defined and item.stdout | trim != ""

    # Track deleted VPCs in summary
    - name: Set VPC deletion results in summary
      set_fact:
        cleanup_summary: "{{ cleanup_summary | combine({
          'vpcs_deleted': ((vpc_deletion.results | default([]) | selectattr('failed', 'undefined') | list | length) + (force_vpc_delete.results | default([]) | selectattr('failed', 'undefined') | list | length))}) }}"
      when: all_vpcs_to_delete | length > 0
    
    # Add these tasks to confirm VPC deletion
    - name: Verify VPC deletion
      amazon.aws.ec2_vpc_net_info:
        region: "{{ aws_region }}"
        filters:
          "tag:deployment_id": "{{ deployment_id }}"
      register: vpc_check

    - name: Display cleanup summary
      debug:
        msg:
          - "Cleanup Summary:"
          - "Redirector instance deleted: {{ redirector_deleted | default('N/A') }}"
          - "C2 instance deleted: {{ c2_deleted | default('N/A') }}"
          - "VPC resources deleted: {{ vpc_check.vpcs | length == 0 }}"
      when: not disable_summary | default(false)

    # STEP 14: Delete key pairs
    - name: Find key pairs by name patterns
      amazon.aws.ec2_key:
        name: "{{ item }}"
        region: "{{ aws_region }}"
        state: present
      register: keys_check
      ignore_errors: yes
      with_items:
        - "{{ redirector_name }}"
        - "{{ c2_name }}"
        - "{{ tracker_name }}"
        
    - name: Delete key pairs
      amazon.aws.ec2_key:
        name: "{{ item.invocation.module_args.name }}"
        region: "{{ aws_region }}"
        state: absent
      loop: "{{ keys_check.results }}"
      when: keys_check.results | length > 0 and item.failed is not defined and item.key is defined
      register: deleted_keys
      
    - name: Count deleted keys
      set_fact:
        cleanup_summary: "{{ cleanup_summary | combine({
          'keypairs_deleted': (deleted_keys.results | default([]) | selectattr('changed', 'defined') | selectattr('changed') | list | length)}) }}"
        
    # Add this after your existing key pair finding task
    - name: Find c2deploy key pairs
      amazon.aws.ec2_key:
        name: "c2deploy_{{ deployment_id }}"
        region: "{{ aws_region }}"
        state: present
      register: c2deploy_key_check
      ignore_errors: yes
      
    - name: Delete c2deploy key pairs
      amazon.aws.ec2_key:
        name: "c2deploy_{{ deployment_id }}"
        region: "{{ aws_region }}"
        state: absent
      when: not c2deploy_key_check.failed | default(true)
      register: deleted_c2deploy_key

    # STEP 15: Delete SSH key files
    - name: Delete SSH key files
      file:
        path: "{{ item }}"
        state: absent
      with_items:
        - "~/.ssh/{{ redirector_name }}.pem"
        - "~/.ssh/{{ c2_name }}.pem"
        - "~/.ssh/{{ tracker_name }}.pem"
        - "~/.ssh/c2deploy_{{ deployment_id }}.pem"  # Fix: add .pem extension
        - "~/.ssh/c2deploy_{{ deployment_id }}.pub"
      ignore_errors: yes
      register: deleted_ssh_files
      
    - name: Count deleted SSH files
      set_fact:
        cleanup_summary: "{{ cleanup_summary | combine({
          'ssh_files_deleted': (deleted_ssh_files.results | selectattr('changed', 'defined') | selectattr('changed') | list | length)}) }}"
    
    # Remove infrastructure state file - fix path to include deployment_id
    - name: Remove infrastructure state file
      file:
        path: "infrastructure_state_{{ deployment_id }}.json"
        state: absent
      ignore_errors: yes
      register: infra_file
      
    # STEP 16: Enhanced and Accurate Cleanup Summary
    - name: Enhanced cleanup summary
      debug:
        msg:
          - "=========================================================="
          - "            AWS CLEANUP SUMMARY: {{ deployment_id }}       "
          - "=========================================================="
          - "EC2 Instances:     {{ cleanup_summary.instances_found | default(0) }} found, {{ terminated_instances.results | default([]) | length }} terminated"
          - "Security Groups:   {{ cleanup_summary.security_groups_found | default(0) }} found, {{ deleted_sgs.results | default([]) | length }} deleted"
          - "Network Interfaces: {{ cleanup_summary.enis_found | default(0) }} found, {{ deleted_enis.results | default([]) | length }} deleted"
          - "VPCs:              {{ cleanup_summary.vpcs_found | default(0) }} found, {{ cleanup_summary.vpcs_deleted | default(0) }} deleted"
          - "Key Pairs:         {{ cleanup_summary.keypairs_deleted | default(0) }} deleted" 
          - "SSH Key Files:     {{ cleanup_summary.ssh_files_deleted | default(0) }} deleted"
          - "Infrastructure file: {{ 'Removed' if infra_file.changed else 'Not found' }}"
          - "=========================================================="
          - "CLEANUP {{ 'COMPLETED' if (cleanup_summary.vpcs_deleted | default(0) == cleanup_summary.vpcs_found | default(0)) else 'PARTIAL - SOME RESOURCES MAY REMAIN' }}"
          - "========================================================="