#!/bin/bash
# License: GPL
# Author: Steven Shiau <steven _at_ clonezilla org>
# Description: Program to generate JSON file from lsblk output with ID_PATH_TAG, excluding loop* devices
# This file contains code generated by Grok, created by xAI.
# Improved by Google's Gemini for efficiency and robustness.

USAGE() {
    echo "$0 - To generate JSON file from lsblk output with ID_PATH_TAG, excluding loop* devices"
    echo "Usage:"
    echo "To run $0:"
    echo "$0 OUTPUT_FILE"
    echo
} # end of USAGE

####################
### Main program ###
####################

if [ "$#" -ne 1 ] || [[ "$1" == -* ]]; then
    USAGE >&2
    exit 1
fi
ocs_out_f="$1"

# Ensure udev has processed all devices
udevadm settle

# Run lsblk with JSON output, excluding loop, ram, and rom devices (-e 1,7,11)
lsblk_output=$(LC_ALL=C lsblk -J -o name,type,size,model,fstype,serial,label,parttype -e 1,7,11 -x name 2>/dev/null)

# Check if lsblk output is empty or contains no devices
if [ -z "$lsblk_output" ] || [ "$(echo "$lsblk_output" | jq '.blockdevices | length')" -eq 0 ]; then
    echo "[]" > "$ocs_out_f"
    exit 0
fi

# Process the entire JSON output
echo "$lsblk_output" | jq -c '.blockdevices[]' | while IFS= read -r device_json; do
    # Extract name to query udevadm
    name=$(echo "$device_json" | jq -r '.name')
    dev_path="/dev/$name"

    # Query udevadm for ID_PATH_TAG
    id_path_tag=$(udevadm info --query=property --name="$dev_path" 2>/dev/null | grep '^ID_PATH_TAG=' | cut -d'=' -f2)

    # If ID_PATH_TAG is empty, set it to "N/A"
    id_path_tag=${id_path_tag:-N/A}

    # Safely inject the ID path tag, handle nulls, and replace spaces and quotes with underscores.
    echo "$device_json" | jq --arg id_path_tag "$id_path_tag" '
        . + {id_path_tag: $id_path_tag} |
        with_entries(
            if .value == null then
                .value = ""
            elif .value | type == "string" then
                # Replaces double quotes, single quotes, and spaces with an underscore
                .value |= gsub("[\"'\'' ]"; "_")
            else
                .
            end
        )
    '
done | jq -s . > "$ocs_out_f"
