#!/bin/bash

# GremlinModes Update Script
# This script updates an existing GremlinModes installation

# Text formatting
BOLD='\033[1m'
GREMLIN='\033[1;38;2;31;204;0m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
RED='\033[0;31m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color

# Banner
echo -e "${BOLD}${GREMLIN}"
echo "   ▄▄ • ▄▄▄  ▄▄▄ .• ▌ ▄ ·. ▄▄▌  ▪   ▐ ▄ • ▌ ▄ ·.       ·▄▄▄▄  ▄▄▄ ..▄▄ · "
echo "  ▐█ ▀ ▪▀▄ █·▀▄.▀··██ ▐███▪██•  ██ •█▌▐█·██ ▐███▪▪     ██▪ ██ ▀▄.▀·▐█ ▀. "
echo "  ▄█ ▀█▄▐▀▀▄ ▐▀▀▪▄▐█ ▌▐▌▐█·██▪  ▐█·▐█▐▐▌▐█ ▌▐▌▐█· ▄█▀▄ ▐█· ▐█▌▐▀▀▪▄▄▀▀▀█▄"
echo "  ▐█▄▪▐█▐█•█▌▐█▄▄▌██ ██▌▐█▌▐█▌▐▌▐█▌██▐█▌██ ██▌▐█▌▐█▌.▐▌██. ██ ▐█▄▄▌▐█▄▪▐█"
echo "  ·▀▀▀▀ .▀  ▀ ▀▀▀ ▀▀  █▪▀▀▀.▀▀▀ ▀▀▀▀▀ █▪▀▀  █▪▀▀▀ ▀█▄▀▪▀▀▀▀▀•  ▀▀▀  ▀▀▀▀ "
echo -e "${NC}"
echo -e "${BOLD}Update${NC}"
echo ""

# Determine the directory of the current script
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

# Location of the source GremlinModes installation
SOURCE_DIR=""

# Check if the .data directory and history file exist in the source installation
if [ -f "$SCRIPT_DIR/../.data/history.json" ]; then
    SOURCE_DIR="$SCRIPT_DIR/.."
elif [ -f "$SCRIPT_DIR/.data/history.json" ]; then
    SOURCE_DIR="$SCRIPT_DIR"
else
    echo -e "${RED}Error: Could not find source GremlinModes installation.${NC}"
    echo -e "${YELLOW}Please provide the path to the GremlinModes source installation:${NC}"
    read -p "> " source_path

    if [ -z "$source_path" ]; then
        echo -e "${RED}No path provided. Exiting.${NC}"
        exit 1
    fi

    # Expand ~ to home directory if present
    source_path="${source_path/#\~/$HOME}"

    # Handle relative paths by converting to absolute paths
    if [[ ! "$source_path" = /* ]]; then
        source_path="$(pwd)/$source_path"
    fi

    if [ ! -d "$source_path" ]; then
        echo -e "${RED}Error: Directory $source_path does not exist. Exiting.${NC}"
        exit 1
    fi

    SOURCE_DIR="$source_path"
fi

# Check if the history file exists
if [ ! -f "$SOURCE_DIR/.data/history.json" ]; then
    echo -e "${RED}Error: No installation history found in $SOURCE_DIR/.data/history.json${NC}"
    exit 1
fi

# Read the installation history
echo -e "${BLUE}Reading installation history...${NC}"

# Check if jq is available
if command -v jq &> /dev/null; then
    # Use jq to parse the JSON
    installation_count=$(jq '.installations | length' "$SOURCE_DIR/.data/history.json")

    if [ "$installation_count" -eq 0 ]; then
        echo -e "${RED}Error: No installations found in history.${NC}"
        exit 1
    fi

    echo -e "${GREEN}Found $installation_count installation(s) in history.${NC}"

    # Display the installations for user selection
    echo -e "${BLUE}Select an installation to update:${NC}"

    for (( i=0; i<$installation_count; i++ )); do
        path=$(jq -r ".installations[$i].path" "$SOURCE_DIR/.data/history.json")
        install_date=$(jq -r ".installations[$i].date" "$SOURCE_DIR/.data/history.json")

        # Check if there's an update history for this installation
        update_count=$(jq -r ".installations[$i].updates | length // 0" "$SOURCE_DIR/.data/history.json")

        if [ "$update_count" -gt 0 ]; then
            last_update=$(jq -r ".installations[$i].updates[-1].date" "$SOURCE_DIR/.data/history.json")
            formatted_date=$(date -d "$last_update" "+%B %d, %Y at %I:%M%p" 2>/dev/null || echo "$last_update")
            echo "  $((i+1)). $path (Installed on $install_date, Last updated $formatted_date)"
        else
            echo "  $((i+1)). $path (Installed on $install_date)"
        fi
    done
else
    echo -e "${YELLOW}Warning: jq is not installed. Using basic parsing.${NC}"

    # Extract installations using grep and sed
    installations=$(grep -o '"path":"[^"]*"' "$SOURCE_DIR/.data/history.json" | sed 's/"path":"//g' | sed 's/"//g')
    dates=$(grep -o '"date":"[^"]*"' "$SOURCE_DIR/.data/history.json" | sed 's/"date":"//g' | sed 's/"//g')

    # Create arrays from the extracted data
    IFS=$'\n' read -d '' -r -a installation_paths <<< "$installations"
    IFS=$'\n' read -d '' -r -a installation_dates <<< "$dates"

    installation_count=${#installation_paths[@]}

    if [ "$installation_count" -eq 0 ]; then
        echo -e "${RED}Error: No installations found in history.${NC}"
        exit 1
    fi

    echo -e "${GREEN}Found $installation_count installation(s) in history.${NC}"

    # Display the installations for user selection
    echo -e "${BLUE}Select an installation to update:${NC}"

    for (( i=0; i<$installation_count; i++ )); do
        echo "  $((i+1)). ${installation_paths[$i]} (Installed on ${installation_dates[$i]})"
    done
fi

# Get user selection
read -p "> " selection

# Validate user selection
if ! [[ "$selection" =~ ^[0-9]+$ ]]; then
    echo -e "${RED}Error: Please enter a number.${NC}"
    exit 1
fi

if [ "$selection" -lt 1 ] || [ "$selection" -gt "$installation_count" ]; then
    echo -e "${RED}Error: Selection out of range.${NC}"
    exit 1
fi

# Get the selected installation path
if command -v jq &> /dev/null; then
    selected_path=$(jq -r ".installations[$((selection-1))].path" "$SOURCE_DIR/.data/history.json")
else
    selected_path=${installation_paths[$((selection-1))]}
fi

# Verify that the selected path still exists
if [ ! -d "$selected_path" ]; then
    echo -e "${RED}Error: Selected installation directory $selected_path does not exist.${NC}"
    exit 1
fi

echo -e "${GREEN}Selected installation: $selected_path${NC}"

# Update options
echo -e "${BLUE}What would you like to update?${NC}"
echo "  1. Everything (agents, instructions, and templates)"
echo "  2. Agents only"
echo "  3. Instructions only"
echo "  4. Templates only"
read -p "> " update_option

case $update_option in
    1)
        update_agents=true
        update_instructions=true
        update_templates=true
        ;;
    2)
        update_agents=true
        update_instructions=false
        update_templates=false
        ;;
    3)
        update_agents=false
        update_instructions=true
        update_templates=false
        ;;
    4)
        update_agents=false
        update_instructions=false
        update_templates=true
        ;;
    *)
        echo -e "${RED}Invalid option. Exiting.${NC}"
        exit 1
        ;;
esac

# Create a timestamp for the backup folder
TIMESTAMP=$(date +%Y-%m-%d-%H%M%S)

# Create centralized backup directory for this update
BACKUP_DIR="$selected_path/.gremlinmodes/backups/$TIMESTAMP"
mkdir -p "$BACKUP_DIR"

echo -e "${BLUE}All backups will be stored in $BACKUP_DIR${NC}"

# Perform the update
echo -e "${BLUE}Updating GremlinModes installation at $selected_path...${NC}"

# Update agents
if [ "$update_agents" = true ]; then
    echo -e "${BLUE}Updating agents...${NC}"

    # Source agents directory
    source_agents_dir="$SOURCE_DIR/agents"

    # Destination agents directory
    dest_agents_dir="$selected_path/.gremlinmodes/agents"

    # Check if source agents directory exists
    if [ -d "$source_agents_dir" ]; then
        # Create backup of existing agents
        if [ -d "$dest_agents_dir" ]; then
            echo -e "${YELLOW}Backing up existing agents${NC}"
            mkdir -p "$BACKUP_DIR/.gremlinmodes/agents"
            cp -r "$dest_agents_dir/"* "$BACKUP_DIR/.gremlinmodes/agents/" 2>/dev/null || true
        else
            mkdir -p "$dest_agents_dir"
        fi

        # Copy new agents
        echo -e "${GREEN}Copying new agents...${NC}"
        cp -r "$source_agents_dir/"* "$dest_agents_dir/" 2>/dev/null || true
    else
        echo -e "${YELLOW}Warning: Source agents directory not found. Skipping agent update.${NC}"
    fi
fi

# Update instructions
if [ "$update_instructions" = true ]; then
    echo -e "${BLUE}Updating instructions...${NC}"

    # Source instructions directory
    source_instructions_dir="$SOURCE_DIR/global-instructions"

    # Destination instructions directory
    dest_instructions_dir="$selected_path/gremlinmodes/instructions/global"

    # Check if source instructions directory exists
    if [ -d "$source_instructions_dir" ]; then
        # Create backup of existing instructions
        if [ -d "$dest_instructions_dir" ]; then
            echo -e "${YELLOW}Backing up existing instructions${NC}"
            mkdir -p "$BACKUP_DIR/gremlinmodes/instructions/global"
            cp -r "$dest_instructions_dir/"* "$BACKUP_DIR/gremlinmodes/instructions/global/" 2>/dev/null || true
        else
            mkdir -p "$dest_instructions_dir"
        fi

        # Copy only the existing global instruction files (01-04)
        echo -e "${GREEN}Copying instruction files...${NC}"
        if [ -f "$source_instructions_dir/01-documentation-standards.md" ]; then
            cp "$source_instructions_dir/01-documentation-standards.md" "$dest_instructions_dir/"
        fi
        if [ -f "$source_instructions_dir/02-file-management.md" ]; then
            cp "$source_instructions_dir/02-file-management.md" "$dest_instructions_dir/"
        fi
        if [ -f "$source_instructions_dir/03-cross-references.md" ]; then
            cp "$source_instructions_dir/03-cross-references.md" "$dest_instructions_dir/"
        fi
        if [ -f "$source_instructions_dir/04-folder-structure.md" ]; then
            cp "$source_instructions_dir/04-folder-structure.md" "$dest_instructions_dir/"
        fi
    else
        # Check if artifacts directory exists
        source_artifacts_dir="$SOURCE_DIR/artifacts"
        if [ -d "$source_artifacts_dir" ]; then
            # Create backup of existing instructions
            if [ -d "$dest_instructions_dir" ]; then
                echo -e "${YELLOW}Backing up existing instructions${NC}"
                mkdir -p "$BACKUP_DIR/gremlinmodes/instructions/global"
                cp -r "$dest_instructions_dir/"* "$BACKUP_DIR/gremlinmodes/instructions/global/" 2>/dev/null || true
            else
                mkdir -p "$dest_instructions_dir"
            fi

            # Copy artifacts as instructions
            echo -e "${GREEN}Copying instructions from artifacts...${NC}"
            if [ -f "$source_artifacts_dir/01-documentation-standards.md" ]; then
                cp "$source_artifacts_dir/01-documentation-standards.md" "$dest_instructions_dir/"
            fi
            if [ -f "$source_artifacts_dir/02-file-management.md" ]; then
                cp "$source_artifacts_dir/02-file-management.md" "$dest_instructions_dir/"
            fi
            if [ -f "$source_artifacts_dir/03-cross-references.md" ]; then
                cp "$source_artifacts_dir/03-cross-references.md" "$dest_instructions_dir/"
            fi
            if [ -f "$source_artifacts_dir/04-folder-structure.md" ]; then
                cp "$source_artifacts_dir/04-folder-structure.md" "$dest_instructions_dir/"
            fi
        else
            echo -e "${YELLOW}Warning: Source instructions directory not found. Skipping instruction update.${NC}"
        fi
    fi
fi

# Update templates
if [ "$update_templates" = true ]; then
    echo -e "${BLUE}Updating templates...${NC}"

    # Source templates directory
    source_templates_dir="$SOURCE_DIR/templates"

    # Destination templates directory
    dest_templates_dir="$selected_path/gremlinmodes/templates"

    # Check if source templates directory exists
    if [ -d "$source_templates_dir" ]; then
        # Create backup of existing templates
        if [ -d "$dest_templates_dir" ]; then
            echo -e "${YELLOW}Backing up existing templates${NC}"
            mkdir -p "$BACKUP_DIR/gremlinmodes/templates"
            cp -r "$dest_templates_dir/"* "$BACKUP_DIR/gremlinmodes/templates/" 2>/dev/null || true
        else
            mkdir -p "$dest_templates_dir"
        fi

        # Copy new templates
        echo -e "${GREEN}Copying new templates...${NC}"
        cp -r "$source_templates_dir/"* "$dest_templates_dir/" 2>/dev/null || true
    else
        echo -e "${YELLOW}Warning: Source templates directory not found. Skipping template update.${NC}"
    fi
fi

# Update scripts
echo -e "${BLUE}Updating scripts...${NC}"

# Source scripts directory
source_scripts_dir="$SOURCE_DIR/scripts"

# Check if agent.sh exists in the source scripts directory
if [ -d "$source_scripts_dir" ] && [ -f "$source_scripts_dir/agent.sh" ]; then
    # Backup existing agent.sh
    if [ -f "$selected_path/agent.sh" ]; then
        echo -e "${YELLOW}Backing up existing agent.sh${NC}"
        mkdir -p "$BACKUP_DIR"
        cp "$selected_path/agent.sh" "$BACKUP_DIR/agent.sh"
    fi

    # Copy new agent.sh
    echo -e "${GREEN}Copying new agent.sh...${NC}"
    cp "$source_scripts_dir/agent.sh" "$selected_path/"
    chmod +x "$selected_path/agent.sh"
else
    # Check if agent.sh exists at the root of the source directory
    if [ -f "$SOURCE_DIR/agent.sh" ]; then
        # Backup existing agent.sh
        if [ -f "$selected_path/agent.sh" ]; then
            echo -e "${YELLOW}Backing up existing agent.sh${NC}"
            mkdir -p "$BACKUP_DIR"
            cp "$selected_path/agent.sh" "$BACKUP_DIR/agent.sh"
        fi

        # Copy new agent.sh
        echo -e "${GREEN}Copying new agent.sh...${NC}"
        cp "$SOURCE_DIR/agent.sh" "$selected_path/"
        chmod +x "$selected_path/agent.sh"
    else
        echo -e "${YELLOW}Warning: Could not find agent.sh script. Skipping script update.${NC}"
    fi
fi

# Do NOT copy update.sh - it should always run from the source GremlinModes folder
# We only need to update agent.sh in the destination project

# Update installation history
echo -e "${BLUE}Updating installation history...${NC}"
# Get current date and time
current_datetime=$(date +"%Y-%m-%d %H:%M:%S")

# Use jq if available to update the history file, otherwise use a temporary file approach
if command -v jq &> /dev/null; then
    # Check if the installation already has an updates array
    has_updates=$(jq -r ".installations[$((selection-1))].updates != null" "$SOURCE_DIR/.data/history.json" 2>/dev/null || echo "false")

    if [ "$has_updates" = "true" ]; then
        # Add to existing updates array
        jq --arg idx "$((selection-1))" --arg date "$current_datetime" --arg items "$(echo "$update_agents $update_instructions $update_templates" | tr ' ' '_')" \
            '.installations[$idx | tonumber].updates += [{"date": $date, "items": $items}]' "$SOURCE_DIR/.data/history.json" > "$SOURCE_DIR/.data/history.json.tmp" && \
            mv "$SOURCE_DIR/.data/history.json.tmp" "$SOURCE_DIR/.data/history.json"
    else
        # Create updates array
        jq --arg idx "$((selection-1))" --arg date "$current_datetime" --arg items "$(echo "$update_agents $update_instructions $update_templates" | tr ' ' '_')" \
            '.installations[$idx | tonumber].updates = [{"date": $date, "items": $items}]' "$SOURCE_DIR/.data/history.json" > "$SOURCE_DIR/.data/history.json.tmp" && \
            mv "$SOURCE_DIR/.data/history.json.tmp" "$SOURCE_DIR/.data/history.json"
    fi
else
    # Backup approach if jq is not available - create a simple update marker
    echo -e "${YELLOW}Unable to update history.json properly without jq. Creating a simple marker file.${NC}"
    echo "Updated on $current_datetime" > "$selected_path/.gremlinmodes/last_update.txt"
fi

# Update the GremlinModes README.md to reflect the correct documentation structure
if [ -f "$selected_path/gremlinmodes/README.md" ]; then
    # Check if the README mentions non-existent instruction files
    if grep -q "05-agent-coordination.md\|06-mode-specific-instructions.md\|07-activation-and-handoff.md" "$selected_path/gremlinmodes/README.md"; then
        echo -e "${BLUE}Updating README.md to reflect the correct documentation files...${NC}"

        # Backup the existing README
        mkdir -p "$BACKUP_DIR/gremlinmodes"
        cp "$selected_path/gremlinmodes/README.md" "$BACKUP_DIR/gremlinmodes/README.md"

        # Create a temporary file with the updated content
        cat > "$selected_path/gremlinmodes/README.md.tmp" << 'EOFREADME'
# GremlinModes Project Structure

This structure has been generated for your GremlinModes implementation.

## Core Principles

The GremlinModes framework is built on these core principles:

1. **Mission-Driven Agent Roles**: Each agent has a clear purpose and passionate domain focus
2. **Documentation Proportionate to Task Type**: Scale documentation based on agent function
3. **Streamlined Sequential Collaboration**: Clear handoffs using hardcoded mode slugs
4. **Status Documentation at Key Points**: Track progress at workflow transition points
5. **Execution over Documentation**: Focus on action, not excessive documentation

## Directory Structure

GremlinModes organizes all agent work within this standardized structure:

```
/gremlinmodes/             # Root folder for all agent documentation
  ├── tasks/               # Development and implementation tasks
  ├── bugs/                # Bug reports and fixes
  ├── designs/             # Design tasks and UI/UX work
  ├── audits/              # Code and system audits
  ├── products/            # Product planning and feature development
  ├── docs/                # Final documentation repository
  ├── tests/               # Testing projects
  ├── marketing/           # Marketing projects (SEO, etc.)
  ├── inputs/              # User-provided task documentation
  └── templates/           # Documentation templates
      ├── status.md        # Status tracking template
      ├── shared-data.md   # Shared data template
      ├── overview.md      # Task overview template
      └── final-report.md  # Final report template

/.gremlinmodes/            # Project-specific configurations
  ├── config.json          # Configuration settings
  ├── custom-instructions/ # Project-specific agent instructions
  ├── backups/             # Backups from updates
  └── agents/              # Agent configuration files
```

## Task Folder Naming Convention

All task folders must follow this pattern:
```
{prefix}-{sequential_number}-{short-descriptive-name}
```

Examples:
- `tsk-023-auth-flow-implementation`
- `bug-011-user-login-failure`
- `dsn-001-dashboard-redesign`

## Agent Workflow

The GremlinModes framework follows a streamlined sequential collaboration pattern:

1. **Orchestrator** → Plans and delegates to first specialized agent
2. **Specialist 1** → Begins work immediately upon activation
3. **Specialist 1** → Completes work, marks status as "Completed"
4. **Orchestrator** → Activates next agent with explicit `new_task` command
5. **Specialist 2** → Begins work immediately upon activation
6. **Specialist 2** → Completes work, marks status as "Completed"
7. **Orchestrator** → Reviews final output, consolidates documentation

## Usage

**Select an Agent**: Choose which agent or team to work with:
```bash
./agent.sh
```

This will activate the selected agent for use with Roo Code.

**Update GremlinModes**: Update your existing installation:
```bash
./update.sh
```

This will update templates, instructions, and agents with the latest versions.

## Documentation Standards

For complete documentation standards, see:
- [Documentation Standards](/gremlinmodes/instructions/global/01-documentation-standards.md)
- [File Management Guidelines](/gremlinmodes/instructions/global/02-file-management.md)
- [Cross-Reference Guidelines](/gremlinmodes/instructions/global/03-cross-references.md)
- [Folder Structure Standards](/gremlinmodes/instructions/global/04-folder-structure.md)
EOFREADME
        # Replace the original README with the updated one
        mv "$selected_path/gremlinmodes/README.md.tmp" "$selected_path/gremlinmodes/README.md"
    fi
fi

# Check if the backup directory is empty, if so remove it
if [ -z "$(ls -A "$BACKUP_DIR" 2>/dev/null)" ]; then
    echo -e "${YELLOW}No files were backed up, removing empty backup directory.${NC}"
    rmdir "$BACKUP_DIR" 2>/dev/null || true
    # Also try to remove parent directories if empty
    rmdir "$selected_path/.gremlinmodes/backups" 2>/dev/null || true
else
    echo -e "${GREEN}Backups stored in: $BACKUP_DIR${NC}"
fi

echo -e "${GREEN}${BOLD}GremlinModes update complete!${NC}"
echo ""
echo -e "Updated installation at ${BOLD}$selected_path${NC}"
echo ""
echo -e "${BLUE}Updated components:${NC}"
if [ "$update_agents" = true ]; then
    echo -e "- ${BOLD}Agents${NC}"
fi
if [ "$update_instructions" = true ]; then
    echo -e "- ${BOLD}Instructions${NC}"
fi
if [ "$update_templates" = true ]; then
    echo -e "- ${BOLD}Templates${NC}"
fi
echo -e "- ${BOLD}agent.sh${NC}"
echo ""
echo -e "${BLUE}Next Steps:${NC}"
echo -e "1. Navigate to your project folder: cd ${BOLD}$selected_path${NC}"
echo "2. Review updated configuration files"
echo "3. Select an agent to begin working with: ./agent.sh"
echo ""
if [ -d "$BACKUP_DIR" ]; then
    echo -e "${BLUE}Your previous files have been backed up to:${NC}"
    echo -e "${BOLD}$BACKUP_DIR${NC}"
    echo ""
fi
echo -e "${GREMLIN}Made with 💚 mischief by gremlinlabs${NC}"
