#!/bin/bash
set -euo pipefail

# Composable App E2E Test Script
# Tests the composable monorepo template flow:
#   1. Create project (skeleton)
#   2. Add service component
#   3. Add app component
#   4. Optionally customize with Claude
#   5. Deploy and verify
#
# Usage: ./cookbooks/scripts/composable-test.sh <command> <project-name>
# Commands: run, status, teardown

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/common.sh"

# Parse --auto-teardown flag from args
ARGS=("$@")
for i in "${!ARGS[@]}"; do
    if [[ "${ARGS[$i]}" == "--auto-teardown" ]]; then
        AUTO_TEARDOWN="true"
        unset 'ARGS[$i]'
    fi
done
ARGS=("${ARGS[@]}")  # Re-index array

COMMAND="${ARGS[0]:-}"
PROJECT_NAME="${ARGS[1]:-}"

# Register cleanup trap for auto-teardown
register_cleanup_trap

if [[ -z "$COMMAND" || -z "$PROJECT_NAME" ]]; then
    echo "Usage: $0 <command> <project-name>"
    echo "Commands:"
    echo "  run       - Create project with components and deploy"
    echo "  status    - Check project and component status"
    echo "  diagnose  - Deep diagnostic of pipeline and site issues"
    echo "  teardown  - Delete the project"
    exit 1
fi

# Add a component and verify
add_component() {
    local comp_type="$1"
    local comp_name="$2"
    local template="${3:-$comp_type}"

    echo "Adding $comp_type component: $comp_name (template: $template)"

    local payload
    payload=$(jq -n \
        --arg type "$comp_type" \
        --arg name "$comp_name" \
        --arg template "$template" \
        '{type: $type, name: $name, template: $template}')

    local result
    result=$(api_call POST "/projects/$PROJECT_NAME/components" "$payload")

    local path
    path=$(echo "$result" | jq -r '.data.path // .path // ""')

    if [[ -z "$path" ]]; then
        print_error "Failed to add component"
        echo "$result" | jq '.'
        return 1
    fi

    local port
    port=$(echo "$result" | jq -r '.data.port // .port // "N/A"')
    print_success "Added $comp_type/$comp_name at $path (port: $port)"
    return 0
}

run_flow() {
    print_header "Composable App E2E Test"
    echo "Project: $PROJECT_NAME"

    # Step 1: Create project (skeleton)
    print_header "Step 1: Creating project skeleton"
    local create_payload
    create_payload=$(jq -n \
        --arg name "$PROJECT_NAME" \
        --arg desc "Composable app E2E test" \
        '{name: $name, description: $desc}')

    local create_result
    create_result=$(api_call POST "/project" "$create_payload")
    echo "$create_result" | jq '.'

    local domain
    domain=$(echo "$create_result" | jq -r '.data.domain // .domain // ""')

    if [[ -z "$domain" ]]; then
        print_error "Failed to create project"
        exit 1
    fi

    # Track project for auto-cleanup
    CLEANUP_PROJECT="$PROJECT_NAME"

    print_success "Project created with domain: $domain"

    # Step 2: Add backend service
    print_header "Step 2: Adding backend service"
    if ! add_component "service" "api" "service"; then
        exit 1
    fi

    # Step 3: Add frontend app
    print_header "Step 3: Adding frontend app"
    if ! add_component "app-react" "web"; then
        exit 1
    fi

    # Step 4: List components
    print_header "Step 4: Verifying components"
    local components
    components=$(api_call GET "/projects/$PROJECT_NAME/components")
    echo "$components" | jq '.data // .'

    local comp_count
    comp_count=$(echo "$components" | jq '.data.components | length // 0')
    if [[ "$comp_count" -lt 2 ]]; then
        print_warning "Expected 2 components, got $comp_count"
    else
        print_success "All components added successfully"
    fi

    # Step 5: Wait for CI pipeline
    print_header "Step 5: Waiting for CI pipeline"
    if ! wait_for_pipeline "$PROJECT_NAME"; then
        print_warning "Pipeline may have issues, continuing to check site..."
    fi

    # Step 6: Wait for site
    print_header "Step 6: Verifying site is accessible"
    if ! wait_for_site "$domain" 30 5 "$PROJECT_NAME"; then
        print_error "Site not accessible"
        exit 1
    fi

    # Step 7: Test API endpoint
    print_header "Step 7: Testing API endpoint"
    local api_response
    api_response=$(curl -s "https://$domain/api/health" 2>/dev/null || echo '{"error":"failed"}')

    if echo "$api_response" | jq -e '.' > /dev/null 2>&1; then
        print_success "API responded with valid JSON"
        echo "$api_response" | jq '.'
    else
        print_warning "API health check returned non-JSON: $api_response"
    fi

    # Summary
    print_header "E2E Test Results"
    print_success "Project created: $PROJECT_NAME"
    print_success "Components added: $comp_count"
    echo ""
    echo "Site URL: https://$domain"
    echo "Git repo: https://git.threesix.ai/jordan/$PROJECT_NAME"
    echo "CI: https://ci.threesix.ai/jordan/$PROJECT_NAME"
}

check_status() {
    print_header "Project Status: $PROJECT_NAME"

    # Get project info
    echo "Project:"
    api_call GET "/project/$PROJECT_NAME" | jq '.data // .'
    echo ""

    # Get components
    echo "Components:"
    api_call GET "/projects/$PROJECT_NAME/components" | jq '.data // .'
    echo ""

    # Get latest pipelines
    echo "Latest Pipelines:"
    api_call GET "/projects/$PROJECT_NAME/pipelines" | jq '.data[:3] // .'
}

teardown() {
    print_header "Tearing down: $PROJECT_NAME"

    local result
    result=$(api_call DELETE "/project/$PROJECT_NAME")
    echo "$result" | jq '.'

    echo ""
    print_success "Project deleted. Gitea repo preserved."
}

diagnose() {
    print_header "Diagnostic: $PROJECT_NAME"

    # Get project info for domain
    local project
    project=$(api_call GET "/project/$PROJECT_NAME")

    local domain
    domain=$(echo "$project" | jq -r '.data.domain // ""')

    if [[ -z "$domain" ]]; then
        print_error "Project not found or no domain assigned"
        echo "$project" | jq '.'
        return 1
    fi

    echo "Project: $PROJECT_NAME"
    echo "Domain: https://$domain"
    echo "Git: https://git.threesix.ai/$(get_git_owner)/$PROJECT_NAME"
    echo "CI: https://ci.threesix.ai/$(get_git_owner)/$PROJECT_NAME"

    # Run pipeline diagnostics
    diagnose_pipeline_failure "$PROJECT_NAME"

    # Run site diagnostics
    diagnose_site_failure "$domain" "$PROJECT_NAME"

    print_header "Summary"
    echo "To retry the pipeline:"
    print_cmd "Push a commit to trigger CI, or manually trigger from Woodpecker UI"
    echo ""
    echo "To check real-time logs:"
    print_cmd "kubectl logs -n projects -l app=$PROJECT_NAME -f"
}

case "$COMMAND" in
    run)
        run_flow
        ;;
    status)
        check_status
        ;;
    diagnose)
        diagnose
        ;;
    teardown)
        teardown
        ;;
    *)
        echo "Unknown command: $COMMAND"
        echo "Valid commands: run, status, diagnose, teardown"
        exit 1
        ;;
esac
