source "$(dirname "${BASH_SOURCE[0]}")/env-init.sh"
#!/usr/bin/env bash

set -euo pipefail

PROGRAM_NAME="${0##*/}"

BASE_URL="https://fid.intellihometech.com"
JSON_FILE="workingOn.json"

VERBOSE_OUTPUT=false      # extra per-app details
DRY_RUN=false             # preview only, no write/backup
TEST_ONLY=false           # test mode: list findings, no JSON write
START_DIR_ARG=""
OLD_FILES_DIR_ARG=""
DAYS_BACK=30              # default lookback window in days
FILES_LIMIT=0             # default: no per-app files

usage() {
    cat >&2 <<EOF
${PROGRAM_NAME} - scan a web root for app directories and build workingOn.json metadata.

Usage:
  ${PROGRAM_NAME} --start-dir <directory> --old-files-dir <directory> [options]

This program:
  - Scans the top level of the given web root for project directories.
  - Only considers project directories modified in the last N days (default: 30).
  - Optionally collects the N most recently modified files under each app directory.
  - Builds JSON metadata and writes it to: ${JSON_FILE}.

Required options:
  --start-dir, -s    Absolute path to the directory to start scanning for projects.
  --old-files-dir, -o
                     Absolute path to a directory related to old files (currently used
                     only as a parameter placeholder).

Optional:
  --days,    -d N    Only consider project directories modified in the last N days.
                     Default: 30.
  --files,   -f N    For each app directory, include a list of up to N most recently
                     modified files under that directory (recursive). Default: 0 (off).
  --verbose, -V      Verbose scanning output (per-app details).
  --dry-run, -v      Preview JSON write only (no backup or modification).
  --test,   -t       Test mode: just list found directories and files; do NOT
                     build or write JSON.
  --help,    -h      Show this help message and exit.
EOF
}

# --- Parse command-line arguments ---
while (( "$#" )); do
    case "$1" in
        --start-dir|-s)
            if [ -n "${2:-}" ] && [ "${2:0:1}" != "-" ]; then
                START_DIR_ARG="$2"
                shift 2
            else
                echo "Error: Argument for $1 is missing or invalid." >&2
                usage
                exit 1
            fi
            ;;
        --old-files-dir|-o)
            if [ -n "${2:-}" ] && [ "${2:0:1}" != "-" ]; then
                OLD_FILES_DIR_ARG="$2"
                shift 2
            else
                echo "Error: Argument for $1 is missing or invalid." >&2
                usage
                exit 1
            fi
            ;;
        --days|-d)
            if [[ -n "${2:-}" && "$2" =~ ^[0-9]+$ ]]; then
                DAYS_BACK="$2"
                shift 2
            else
                echo "Error: --days/-d requires an integer number of days." >&2
                usage
                exit 1
            fi
            ;;
        --files|-f)
            if [[ -n "${2:-}" && "$2" =~ ^[0-9]+$ ]]; then
                FILES_LIMIT="$2"
                shift 2
            else
                echo "Error: --files/-f requires an integer count." >&2
                usage
                exit 1
            fi
            ;;
        --verbose|-V)
            VERBOSE_OUTPUT=true
            shift
            ;;
        --dry-run|-v)
            DRY_RUN=true
            shift
            ;;
        --test|-t)
            TEST_ONLY=true
            shift
            ;;
        --help|-h)
            usage
            exit 0
            ;;
        --)
            shift
            break
            ;;
        -*)
            echo "Error: Unknown option: $1" >&2
            usage
            exit 1
            ;;
        *)
            echo "Error: Unexpected argument: $1" >&2
            usage
            exit 1
            ;;
    esac
done

# --- Validate required arguments ---
if [ -z "$START_DIR_ARG" ]; then
    echo "Error: --start-dir is a required argument." >&2
    usage
    exit 1
fi
if [ -z "$OLD_FILES_DIR_ARG" ]; then
    echo "Error: --old-files-dir is a required argument." >&2
    usage
    exit 1
fi

WEB_ROOT="$START_DIR_ARG"

if [ ! -d "$WEB_ROOT" ]; then
    echo "Error: Specified --start-dir '$WEB_ROOT' does not exist or is not a directory." >&2
    exit 1
fi

# --- Ask about dry-run only if not in test mode and not already specified ---
if [ "$TEST_ONLY" = false ] && [ "$DRY_RUN" = false ]; then
    read -r -p "Run in DRY RUN mode (only show what would change)? (y/N): " ans_dry
    if [[ "$ans_dry" =~ ^[Yy]$ ]]; then
        DRY_RUN=true
    fi
fi

echo "Starting ${PROGRAM_NAME}..."
echo "Scanning web root: $WEB_ROOT"
echo "Base URL for links: $BASE_URL"
echo "Old files directory (provided): $OLD_FILES_DIR_ARG"
echo "Output JSON file: $JSON_FILE"
echo "Date range: last ${DAYS_BACK} day(s) (directory mtime filter)."
echo "Per-app files limit: $FILES_LIMIT"
if [ "$TEST_ONLY" = true ]; then
    echo "Mode: TEST ONLY (just list findings; no JSON build/write)."
elif [ "$DRY_RUN" = true ]; then
    echo "Mode: DRY RUN (no files will be created, modified, or backed up)."
fi
if [ "$VERBOSE_OUTPUT" = true ]; then
    echo "Verbose scanning: enabled."
fi

# structure: array of raw JSON objects (strings) and parallel array of per-app files
APP_DATA_COLLECTED=()
APP_FILES_LIST=()  # flattened; each element is "app_index|/full/path/to/file"

# --- Collect app metadata (directories) and per-app files ---
collected_json_output=$(
    find "$WEB_ROOT" -maxdepth 1 -type d -mtime "-$DAYS_BACK" -print0 2>/dev/null |
    while IFS= read -r -d '' project_dir; do
        [ -z "$project_dir" ] && continue

        # Skip WEB_ROOT itself
        if [[ "$project_dir" == "$WEB_ROOT" ]]; then
            if [ "$VERBOSE_OUTPUT" = true ]; then
                echo "  Skipping base WEB_ROOT directory: $project_dir" >&2
            fi
            continue
        fi

        app_name=$(basename "$project_dir")

        cleaned_web_root="${WEB_ROOT%/}/"
        relative_path="${project_dir#$cleaned_web_root}"

        if [ -f "${project_dir}/index.html" ]; then
            startup_link="${BASE_URL}/${relative_path}/index.html"
        elif [ -f "${project_dir}/index.php" ]; then
            startup_link="${BASE_URL}/${relative_path}/index.php"
        elif [ -f "${project_dir}/app.php" ]; then
            startup_link="${BASE_URL}/${relative_path}/app.php"
        else
            startup_link="${BASE_URL}/${relative_path}/"
        fi

        secondary_link=""
        comment="Automatically discovered project."
        status="new"
        last_updated=$(date +"%Y-%m-%d")

        if [ "$VERBOSE_OUTPUT" = true ]; then
            echo "  Found App: '$app_name'" >&2
            echo "    Directory: $project_dir" >&2
            echo "    Startup Link: $startup_link" >&2
            echo "    Status: $status" >&2
        fi

        # Per-app files list (top N newest under this directory)
        files_for_app=()
        if [ "$FILES_LIMIT" -gt 0 ]; then
            echo "  [Files] Using find command:" >&2
            echo "    find \"$project_dir\" -type f -printf '%T@ %p\\n' | sort -nr | head -n $FILES_LIMIT | cut -d' ' -f2-" >&2

            while IFS= read -r fpath; do
                files_for_app+=( "$fpath" )
            done <<EOF
$(find "$project_dir" -type f -printf '%T@ %p\n' 2>/dev/null \
   | sort -nr \
   | head -n "$FILES_LIMIT" \
   | cut -d' ' -f2-)
EOF
        fi

        # escape for JSON
        ea=${app_name//\"/\\\"}
        ed=${project_dir//\"/\\\"}
        es=${startup_link//\"/\\\"}
        e2=${secondary_link//\"/\\\"}
        ec=${comment//\"/\\\"}
        est=${status//\"/\\\"}
        el=${last_updated//\"/\\\"}

        # embed files array in the app JSON
        printf '{ "appName": "%s", "directory": "%s", "startUp": "%s", "secondaryLink": "%s", "comment": "%s", "status": "%s", "lastUpdated": "%s", "files": [' \
            "$ea" "$ed" "$es" "$e2" "$ec" "$est" "$el"

        if [ "${#files_for_app[@]}" -gt 0 ]; then
            for idx in "${!files_for_app[@]}"; do
                ef=${files_for_app[$idx]//\"/\\\"}
                printf '"%s"' "$ef"
                if [ "$idx" -lt $(( ${#files_for_app[@]} - 1 )) ]; then
                    printf ', '
                fi
            done
        fi

        printf '] }\n'
    done
)

if [ -n "$collected_json_output" ]; then
    mapfile -t APP_DATA_COLLECTED <<< "$(printf '%s\n' "$collected_json_output" | grep -v '^$')"
else
    echo "No project data collected from scanning."
fi

echo "Projects discovered: ${#APP_DATA_COLLECTED[@]}"

# --- TEST MODE: just list what was found and exit ---
if [ "$TEST_ONLY" = true ]; then
    echo
    echo "=== TEST MODE: DIRECTORIES AND FILES FOUND ==="
    if [ ${#APP_DATA_COLLECTED[@]} -eq 0 ]; then
        echo "  (no app directories found in range)"
    else
        for obj in "${APP_DATA_COLLECTED[@]}"; do
            if command -v jq >/dev/null 2>&1; then
                name=$(jq -r '.appName'  <<<"$obj")
                dir=$(jq -r '.directory' <<<"$obj")
                start=$(jq -r '.startUp'  <<<"$obj")
                echo "App: $name"
                echo "  Dir:   $dir"
                echo "  Start: $start"
                echo "  Files:"
                jq -r '.files[]?' <<<"$obj" | sed 's/^/    - /'
            else
                name=$(sed -n 's/.*"appName": *"\([^"]*\)".*/\1/p'  <<<"$obj")
                dir=$(sed -n 's/.*"directory": *"\([^"]*\)".*/\1/p' <<<"$obj")
                start=$(sed -n 's/.*"startUp": *"\([^"]*\)".*/\1/p'   <<<"$obj")
                echo "App: $name"
                echo "  Dir:   $dir"
                echo "  Start: $start"
                echo "  Files:"
                # naive files extraction: look between "files": [ ... ]
                files_block=$(sed -n 's/.*"files": *\[\(.*\)\].*/\1/p' <<<"$obj")
                # split on "," into lines
                IFS=',' read -r -a farray <<<"$files_block"
                for raw in "${farray[@]}"; do
                    ftrim=$(echo "$raw" | sed 's/^ *"//; s/" *$//')
                    [ -n "$ftrim" ] && echo "    - $ftrim"
                done
            fi
            echo
        done
    fi

    echo "TEST MODE complete. No JSON was built or written."
    exit 0
fi

# --- helper to build full JSON object to stdout ---
build_full_json() {
    {
        echo "{"
        echo '  "apps": ['
        for i in "${!APP_DATA_COLLECTED[@]}"; do
            echo "    ${APP_DATA_COLLECTED[$i]}"
            if [ "$i" -lt $(( ${#APP_DATA_COLLECTED[@]} - 1 )) ]; then
                echo "    ,"
            fi
        done
        echo "  ]"
        echo "}"
    }
}

# --- DRY-RUN: show what would be written and exit without touching files ---
if [ "$DRY_RUN" = true ]; then
    echo
    echo "DRY RUN summary:"
    echo "  Target JSON file: $JSON_FILE"
    if [ -f "$JSON_FILE" ]; then
        echo "  Existing file would be backed up to: ${JSON_FILE}.bak.<timestamp>"
    else
        echo "  JSON file does not exist; a new one would be created."
    fi
    echo "  Number of app entries that WOULD be written: ${#APP_DATA_COLLECTED[@]}"
    echo

    read -r -p "Show the JSON that WOULD be written (formatted)? (y/N): " show_preview
    if [[ "$show_preview" =~ ^[Yy]$ ]]; then
        tmp_json=$(build_full_json)

        echo "--- JSON that WOULD be written ---"
        if command -v jq >/dev/null 2>&1; then
            jq . <<<"$tmp_json"
        else
            python3 -m json.tool <<<"$tmp_json" 2>/dev/null || echo "$tmp_json"
        fi
        echo "---------------------------------"
    fi

    echo "No changes have been made (dry run)."
    exit 0
fi

# --- Real write path ---
echo "Proceeding to update $JSON_FILE..."

if [ -f "$JSON_FILE" ]; then
    TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
    BACKUP_FILE="${JSON_FILE}.bak.${TIMESTAMP}"
    cp "$JSON_FILE" "$BACKUP_FILE"
    if [ $? -eq 0 ]; then
        echo "Backed up $JSON_FILE to $BACKUP_FILE"
    else
        echo "Error: Failed to create backup of $JSON_FILE to $BACKUP_FILE." >&2
            exit 1
    fi
else
    echo "$JSON_FILE does not exist. Creating new file."
fi

if [ ${#APP_DATA_COLLECTED[@]} -eq 0 ]; then
    echo "No app data to write. Creating an empty JSON object in $JSON_FILE."
    echo '{ "apps": [] }' > "$JSON_FILE"
else
    build_full_json > "$JSON_FILE"
fi

if [ $? -eq 0 ]; then
    echo "Finished updating $JSON_FILE successfully."
else
    echo "Error: Failed to write to $JSON_FILE. Check permissions." >&2
    exit 1
fi

echo "Script finished."

# --- Optional: view JSON file after real run ---
if [ -f "$JSON_FILE" ]; then
    read -r -p "Do you want to view the contents of $JSON_FILE (formatted JSON)? (y/N): " view_json2
    if [[ "$view_json2" =~ ^[Yy]$ ]]; then
        echo "--- Contents of $JSON_FILE ---"
        if command -v jq >/dev/null 2>&1; then
            jq . "$JSON_FILE"
        else
            python3 -m json.tool "$JSON_FILE" 2>/dev/null || cat "$JSON_FILE"
        fi
        echo "----------------------------"
    fi
fi

