#!/bin/bash

# Ensure jq is installed
if ! command -v jq &> /dev/null; then
    echo "Installing jq..."
    apt-get update -qq && apt-get install -y jq -qq
fi

TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
OUTPUT_FILE="${TIMESTAMP}.txt"
NODE=$(hostname)

echo "Gathering interfaces, VLANs, and IPv4 addresses on node '$NODE'..."

get_data() {
    local type=$1
    local guests=$(pvesh get /nodes/$NODE/$type --output-format json 2>/dev/null)

    echo "$guests" | jq -c '.[]' | while read -r guest; do
        vmid=$(echo "$guest" | jq -r '.vmid')
        name=$(echo "$guest" | jq -r '.name // "unknown"')
        status=$(echo "$guest" | jq -r '.status // "unknown"')

        config=$(pvesh get /nodes/$NODE/$type/$vmid/config --output-format json 2>/dev/null)
        tags=$(echo "$config" | jq -r '.tags // ""')

        # 1. Extract netX interfaces, VLAN tags, and MAC addresses from PVE config
        config_nets=$(echo "$config" | jq -c '
            to_entries |
            map(select(.key | test("^net[0-9]+$"))) |
            map({
                interface: .key,
                vlan: (if (.value | test("tag=[0-9]+")) then (.value | capture("tag=(?<v>\\d+)").v | tonumber) else "untagged" end),
                mac: (if (.value | test("(?i)(?<m>[0-9a-f]{2}(:[0-9a-f]{2}){5})")) then (.value | capture("(?i)(?<m>[0-9a-f]{2}(:[0-9a-f]{2}){5})").m | ascii_downcase) else "" end)
            })
        ')

        ip_list="[]"

        # 2. Fetch IP data mapping MAC -> IPs
        if [ "$status" = "running" ]; then
            if [ "$type" = "qemu" ]; then
                agent_net=$(pvesh get /nodes/$NODE/qemu/$vmid/agent/network-get-interfaces --output-format json 2>/dev/null)
                if [ -n "$agent_net" ] && [ "$agent_net" != "null" ]; then
                    ip_list=$(echo "$agent_net" | jq -c '
                        [ .result[]? | select(.["hardware-address"] != null) |
                          {
                            mac: (.["hardware-address"] | ascii_downcase),
                            ipv4: [ .["ip-addresses"][]? | select(.["ip-address-type"] == "ipv4" and .["ip-address"] != "127.0.0.1") | .["ip-address"] ]
                          }
                        ]
                    ')
                fi
            elif [ "$type" = "lxc" ]; then
                lxc_net=$(pvesh get /nodes/$NODE/lxc/$vmid/interfaces --output-format json 2>/dev/null)
                if [ -n "$lxc_net" ] && [ "$lxc_net" != "null" ]; then
                    ip_list=$(echo "$lxc_net" | jq -c '
                        [ .[]? | select(.hwaddr != null) |
                          {
                            mac: (.hwaddr | ascii_downcase),
                            ipv4: [ (if .inet != null then (.inet | split("/")[0]) else empty end) ]
                          }
                        ]
                    ')
                fi
            fi
        fi

        # 3. Merge the PVE config interfaces with the Guest OS IPs using the MAC address
        merged_nets=$(jq -n --argjson nets "$config_nets" --argjson ips "$ip_list" --arg status "$status" '
            $nets | map(
                . + {
                    ipv4: (
                        .mac as $m |
                        if $status != "running" then ["stopped"]
                        else
                            # Look up IPs by MAC. If no match or no agent, return placeholder array
                            ($ips | map(select(.mac == $m))[0].ipv4 // ["no_ip_found"])
                        end
                    )
                } | del(.mac) # Remove MAC from final output to keep it clean
            )
        ')

        # Output as a single JSON object (renamed 'vlans' to 'interfaces' for accuracy)
        jq -n \
           --arg vmid "$vmid" \
           --arg name "$name" \
           --arg type "$type" \
           --arg tags "$tags" \
           --argjson interfaces "$merged_nets" \
           '{vmid: ($vmid|tonumber), name: $name, type: $type, tags: $tags, interfaces: $interfaces}'
    done
}

# Run for both types and combine
{ get_data "qemu"; get_data "lxc"; } | jq -s '.' > "$OUTPUT_FILE"

echo "Success! Export saved to: $OUTPUT_FILE"