#!/usr/bin/env bash
set -euo pipefail

# Simple script to launch an application or focus it if already running in sway
# Usage: launch-or-focus <command> [--class CLASS] [--title TITLE] [args...]
#
# Examples:
#   launch-or-focus firefox
#   launch-or-focus code --class Code --title "My Project"
#   launch-or-focus kitty --class kitty

CLASS=""
TITLE=""
ARGS=()

# Parse arguments
while [[ $# -gt 0 ]]; do
    case $1 in
        --class)
            CLASS="$2"
            shift 2
            ;;
        --title)
            TITLE="$2"
            shift 2
            ;;
        *)
            ARGS+=("$1")
            shift
            ;;
    esac
done

if [ ${#ARGS[@]} -eq 0 ]; then
    echo "Usage: $0 <command> [--class CLASS] [--title TITLE] [args...]" >&2
    exit 1
fi

COMMAND="${ARGS[0]}"
APP_NAME=$(basename "$COMMAND")
unset 'ARGS[0]'
ARGS=("${ARGS[@]}")

# If class/title were provided as flags, add them to command args (for apps that support them)
if [ -n "$CLASS" ]; then
    ARGS=("--class=$CLASS" "${ARGS[@]}")
fi
if [ -n "$TITLE" ]; then
    ARGS=("--title=$TITLE" "${ARGS[@]}")
fi

# Find window by app_id (sway uses app_id), title, or app name
find_window() {
    local class="$1"
    local title="$2"
    local app="$3"
    
    # If class provided, search by app_id first (sway uses app_id)
    if [ -n "$class" ]; then
        swaymsg -t get_tree | jq -r --arg class "$class" '
            recurse(.nodes[]?, .floating_nodes[]?) |
            select((.app_id | type) == "string" and .app_id == $class) |
            .id
        ' | head -n 1
        return
    fi
    
    # If only title provided, search by title
    if [ -n "$title" ]; then
        swaymsg -t get_tree | jq -r --arg title "$title" '
            recurse(.nodes[]?, .floating_nodes[]?) |
            select((.name | type) == "string" and .name == $title) |
            .id
        ' | head -n 1
        return
    fi
    
    # Fallback to app name (search by app_id)
    swaymsg -t get_tree | jq -r --arg app "$app" '
        recurse(.nodes[]?, .floating_nodes[]?) |
        select((.app_id | type) == "string" and .app_id == $app) |
        .id
    ' | head -n 1
}

# Try to find existing window
WINDOW_ID=$(find_window "$CLASS" "$TITLE" "$APP_NAME")

# Focus if found, otherwise launch
if [ -n "$WINDOW_ID" ] && [ "$WINDOW_ID" != "null" ]; then
    swaymsg "[con_id=$WINDOW_ID]" focus
else
    "$COMMAND" "${ARGS[@]}" >/dev/null 2>&1 &
    disown
fi

