#!/bin/bash

# Function to display usage
usage() {
    echo "Usage: $0 [--app-name <APP_NAME> --port <PORT> --app-dir <APP_DIR> --target <TARGET> --branch <BRANCH>]"
    echo "If no arguments are provided, values will be read from .xbp/xbp.json"
    exit 1
}

# Check if arguments were provided
if [ "$#" -eq 0 ]; then
    echo "No arguments provided, reading from .xbp/xbp.json..."

    # Check if xbp.json exists
    if [ ! -f ".xbp/xbp.json" ]; then
        echo "Error: .xbp/xbp.json not found"
        exit 1
    fi

    # Extract values from xbp.json
    if command -v jq >/dev/null 2>&1; then
        PROJECT_NAME=$(jq -r '.project_name' .xbp/xbp.json)
        PORT=$(jq -r '.port' .xbp/xbp.json)
        APP_DIR=$(jq -r '.build_dir' .xbp/xbp.json)
        CRATE_NAME=$(jq -r '.crate_name' .xbp/xbp.json)
        TARGET=$(jq -r '.target // "rust"' .xbp/xbp.json)
        # Default to rust if target not found
        if [ -z "$TARGET" ]; then
            TARGET="rust"
        fi

        # Check if jq command was successful
        if [ $? -ne 0 ]; then
            echo "Error: Failed to parse .xbp/xbp.json with jq"
            exit 1
        fi

        # Check if jq returned empty values
        if [ -z "$PROJECT_NAME" ] || [ -z "$PORT" ] || [ -z "$APP_DIR" ]; then
            echo "Error: Missing required fields in .xbp/xbp.json"
            exit 1
        fi


    else
        # Fallback method without jq
        PROJECT_NAME=$(grep -o '"project_name": "[^"]*"' .xbp/xbp.json | cut -d'"' -f4)
        PORT=$(grep -o '"port": [0-9]*' .xbp/xbp.json | awk '{print $2}')
        APP_DIR=$(grep -o '"build_dir": "[^"]*"' .xbp/xbp.json | cut -d'"' -f4)
        CRATE_NAME=$(grep -o '"crate_name": "[^"]*"' .xbp/xbp.json | cut -d'"' -f4)
        TARGET=$(grep -o '"target": "[^"]*"' .xbp/xbp.json | cut -d'"' -f4)
        # Default to rust if target not found
        if [ -z "$TARGET" ]; then
            TARGET="rust"
        fi
    fi

    # Set APP_NAME from PROJECT_NAME
    APP_NAME=$PROJECT_NAME
else
    # Parse CLI arguments
    while [[ "$#" -gt 0 ]]; do
        case "$1" in
        --app-name)
            APP_NAME="$2"
            shift 2
            ;;
        --port)
            PORT="$2"
            shift 2
            ;;
        --app-dir)
            APP_DIR="$2"
            shift 2
            ;;
        --target)
            TARGET="$2"
            shift 2
            ;;
        *)
            usage
            ;;
        esac
    done
fi

# Validate inputs
if [[ -z "$APP_NAME" || -z "$PORT" || -z "$APP_DIR" ]]; then
    echo "Error: Missing required parameters"
    usage
fi

# Set default target if not specified
if [[ -z "$TARGET" ]]; then
    TARGET="rust"
    echo "No target specified, defaulting to: $TARGET"
fi

# Validate target
if [[ "$TARGET" != "rust" && "$TARGET" != "nextjs" && "$TARGET" != "python" ]]; then
    echo "Error: Target must be one of: rust, nextjs, python"
    exit 1
fi

# Redeploy $APP_NAME
echo "Redeploying $APP_NAME"
cd "$APP_DIR" || {
    echo "Failed to navigate to $APP_DIR directory"
    exit 1
}

echo "Resetting local changes for $APP_NAME ..."
git reset --hard || {
    echo "Failed to reset local changes for $APP_NAME "
    exit 1
}

echo "Pulling latest changes for $APP_NAME ..."
git pull origin main || {
    echo "Failed to pull latest changes for $APP_NAME "
    exit 1
}

if [[ "$TARGET" == "rust" ]]; then
    echo "Building $APP_NAME ..."
    cargo build --release || {
        echo "Failed to build $APP_NAME "
        exit 1
    }

    echo "Generating docs for $APP_NAME ..."
    cargo d || {
        echo "Failed to generate docs for $APP_NAME "
        exit 1
    }
elif [[ "$TARGET" == "nextjs" ]]; then
    echo "Installing dependencies..."
    pnpm install || {
        echo "Install failed"
        exit 1
    }

    echo "Building..."
    pnpm run build || {
        echo "Build failed"
        exit 1
    }
fi

echo "Stopping existing PM2 process for $APP_NAME ..."
pm2 stop "$APP_NAME" || echo "No existing process found for $APP_NAME. Proceeding..."

if [[ "$TARGET" == "rust" ]]; then
    # Extract crate_name from xbp.json if not already set
    if [ -z "$CRATE_NAME" ]; then
        CRATE_NAME=$(grep -o '"crate_name": "[^"]*"' .xbp/xbp.json | cut -d'"' -f4)
        if [ -z "$CRATE_NAME" ]; then
            echo "Failed to extract crate_name from xbp.json, using default"
            CRATE_NAME="events_suitsbooks"
        fi
    fi

    cp "$APP_DIR/target/release/$CRATE_NAME" ./"$APP_NAME-binary" || {
        echo "Failed to build $APP_NAME "
        exit 1
    }

    echo "Starting $APP_NAME with PM2..."
    pm2 start "./$APP_NAME-binary" --name "$APP_NAME" -- --port $PORT || {
        echo "Failed to start $APP_NAME "
        exit 1
    }
fi

if [[ "$TARGET" == "nextjs" ]]; then
    echo "Starting app with PM2..."
    pm2 start "pnpm run start -p $PORT" --name "$APP_NAME" -- --port $PORT || {
        echo "Failed to start"
        exit 1
    }
fi

echo "Saving PM2 process list for $APP_NAME ..."
pm2 save || {
    echo "Failed to save PM2 process list for $APP_NAME "
    exit 1
}

echo "Updating version information in database..."
# Use the new version increment endpoint
if [ -z "$PROJECT_NAME" ]; then
    PROJECT_NAME=$(grep -o '"project_name": "[^"]*"' .xbp/xbp.json | cut -d'"' -f4)
fi

VERSION_INCREMENT_RESPONSE=$(curl -s --location 'https://api.xbp.app/version/increment' \
    --header 'Content-Type: application/json' \
    --data '{
        "project_name": "'"$PROJECT_NAME"'",
        "increment": "minor"
    }')

echo "Version increment response: $VERSION_INCREMENT_RESPONSE"

echo "Listing all XBP deployments..."
pm2 list --no-color || {
    echo "Failed to deployments."
    exit 1
}

echo "Purging prior deployments..."
pm2 list --no-color | awk '/stopped/ {print $2}' | xargs -I {} pm2 delete {} || {
    echo "Failed to delete stopped processes."
    exit 1
}
pm2 list --no-color | awk '/errored/ {print $2}' | xargs -I {} pm2 delete {} || {
    echo "Failed to delete errored processes"
    exit 1
}

echo "Saving the current deployments list..."
pm2 save || {
    echo "Failed to save deployments list."
    exit 1
}


echo "Operation completed."
