#!/bin/bash
set -euo pipefail

# Feature Development E2E Test Script
# Tests the complete Claude Code + SDLC feature development workflow:
#   1. Create composable project with skeleton
#   2. Add service component
#   3. Create SDLC feature via API
#   4. Invoke Claude to generate spec (via /builds with skeleton command)
#   5. Approve spec via API
#   6. Invoke Claude to generate design
#   7. Approve design via API
#   8. Invoke Claude to break down tasks
#   9. Approve tasks via API
#   10. Invoke Claude to implement first task
#   11. Verify code was generated
#   12. Teardown
#
# Usage: ./cookbooks/scripts/feature-dev-test.sh <command> <project-name>
# Commands: run, status, teardown
#
# This is the definitive E2E test for the SDLC + Claude Code integration.
# It exercises the full feature development workflow from project creation
# to implemented code.

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]:-}"
FEATURE_SLUG="add-hello-endpoint"

# Register cleanup trap for auto-teardown
register_cleanup_trap

if [[ -z "$COMMAND" || -z "$PROJECT_NAME" ]]; then
    echo "Feature Development E2E Test Script"
    echo ""
    echo "Tests the complete Claude Code + SDLC feature development workflow."
    echo ""
    echo "Usage: $0 <command> <project-name> [--auto-teardown]"
    echo ""
    echo "Commands:"
    echo "  run       - Execute full feature development flow"
    echo "  status    - Check project and SDLC status"
    echo "  teardown  - Delete the project"
    echo ""
    echo "Examples:"
    echo "  $0 run feature-dev-test"
    echo "  $0 run test-feat --auto-teardown"
    echo "  $0 status feature-dev-test"
    echo "  $0 teardown feature-dev-test"
    echo ""
    echo "Environment Variables:"
    echo "  RDEV_API_URL - rdev API base URL"
    echo "  RDEV_API_KEY - rdev API key"
    echo "  GITEA_TOKEN  - Gitea API token (optional, for repo verification)"
    exit 1
fi

# Check response for success/error
check_response() {
    local response="$1"
    local step="$2"

    local error
    error=$(echo "$response" | jq -r '.error // ""')
    if [[ -n "$error" && "$error" != "" && "$error" != "null" ]]; then
        print_error "$step failed: $error"
        echo "$response" | jq '.'
        return 1
    fi
    return 0
}

# Wait for a build to complete
# Arguments: task_id step_name [max_attempts]
wait_for_build_step() {
    local task_id="$1"
    local step_name="$2"
    local max_attempts="${3:-120}"  # 10 minutes default (5s * 120)
    local attempt=0

    echo "  Waiting for build to complete (task: $task_id)..."

    while [[ $attempt -lt $max_attempts ]]; do
        local result
        result=$(api_call GET "/builds/$task_id")
        local status
        status=$(echo "$result" | jq -r '.data.status // .status // "unknown"')

        case "$status" in
            completed)
                local success
                success=$(echo "$result" | jq -r '.data.result.success // .result.success // false')
                if [[ "$success" == "true" ]]; then
                    print_success "$step_name completed successfully"
                    return 0
                else
                    print_error "$step_name completed but failed:"
                    echo "$result" | jq '.data.result // .result'
                    return 1
                fi
                ;;
            failed)
                print_error "$step_name failed:"
                echo "$result" | jq '.'
                return 1
                ;;
            running)
                echo "    Build running... (attempt $((attempt + 1))/$max_attempts)"
                ;;
            pending)
                echo "    Build pending... (attempt $((attempt + 1))/$max_attempts)"
                ;;
            *)
                echo "    Unknown status: $status (attempt $((attempt + 1))/$max_attempts)"
                ;;
        esac

        sleep 5
        ((attempt++))
    done

    print_error "Timeout waiting for $step_name to complete"
    return 2
}

# Submit a build and wait for completion
# Arguments: project_id prompt step_name
submit_build_and_wait() {
    local project_id="$1"
    local prompt="$2"
    local step_name="$3"

    local git_owner
    git_owner=$(get_git_owner)
    local git_clone_url="https://git.threesix.ai/${git_owner}/${project_id}.git"

    echo "  Submitting build: $prompt"

    local payload
    payload=$(jq -n \
        --arg prompt "$prompt" \
        --arg git_clone_url "$git_clone_url" \
        '{
            prompt: $prompt,
            auto_commit: true,
            auto_push: true,
            git_clone_url: $git_clone_url
        }')

    local result
    result=$(api_call POST "/projects/$project_id/builds" "$payload")

    if ! check_response "$result" "Submit build"; then
        return 1
    fi

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

    if [[ -z "$task_id" ]]; then
        print_error "No task_id in response"
        echo "$result" | jq '.'
        return 1
    fi

    wait_for_build_step "$task_id" "$step_name"
}

# Approve an SDLC artifact
# Arguments: project_id feature_slug artifact_type
approve_artifact() {
    local project_id="$1"
    local feature_slug="$2"
    local artifact_type="$3"

    echo "  Approving $artifact_type artifact..."

    local result
    result=$(api_call POST "/projects/$project_id/sdlc/features/$feature_slug/artifacts/$artifact_type/approve" "{}")

    if check_response "$result" "Approve $artifact_type"; then
        print_success "$artifact_type artifact approved"
        return 0
    fi
    return 1
}

# Add a component to the project
add_component() {
    local comp_type="$1"
    local comp_name="$2"

    echo "Adding $comp_type component: $comp_name"

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

    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

    print_success "Added $comp_type/$comp_name at $path"
    return 0
}

# Verify the feature artifacts exist in Gitea
verify_artifacts() {
    local project_id="$1"
    local feature_slug="$2"

    local git_owner
    git_owner=$(get_git_owner)

    print_header "Verifying Feature Artifacts"

    local artifacts=("spec.md" "design.md" "tasks.md")
    local all_found=true

    for artifact in "${artifacts[@]}"; do
        local path=".sdlc/features/$feature_slug/$artifact"
        echo "  Checking $path..."

        local check
        check=$(curl -s "https://git.threesix.ai/api/v1/repos/$git_owner/$project_id/contents/$path" \
            -H "Authorization: token ${GITEA_TOKEN:-}" 2>/dev/null | jq -r '.name // "not found"')

        if [[ "$check" == "$artifact" ]]; then
            print_success "  $artifact exists"
        else
            print_warning "  $artifact not found"
            all_found=false
        fi
    done

    if [[ "$all_found" == "true" ]]; then
        print_success "All artifacts verified"
        return 0
    else
        print_warning "Some artifacts missing (may still be propagating)"
        return 0  # Don't fail on verification, may be timing
    fi
}

# Main run flow
run_flow() {
    print_header "Feature Development E2E Test"
    echo "Project: $PROJECT_NAME"
    echo "Feature: $FEATURE_SLUG"
    echo ""

    # =========================================================================
    # 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 "Feature development 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 service component
    # =========================================================================
    print_header "Step 2: Adding service component"

    if ! add_component "service" "api"; then
        exit 1
    fi

    # Wait for git sync
    echo "  Waiting for git sync..."
    sleep 10

    # =========================================================================
    # Step 3: Create SDLC feature via build (using worker pod)
    # =========================================================================
    # Note: Composable projects don't have dedicated pods, so we use builds
    # to execute SDLC commands on worker pods that clone the repo.
    print_header "Step 3: Creating SDLC feature via build"

    # Initialize SDLC and create feature in one build
    if ! submit_build_and_wait "$PROJECT_NAME" \
        "Initialize SDLC for this project and create a feature with slug '$FEATURE_SLUG' and title 'Add /hello endpoint to API service'. Use the sdlc CLI: 'sdlc init' then 'sdlc feature create $FEATURE_SLUG \"Add /hello endpoint to API service\"'" \
        "SDLC initialization"; then
        print_error "SDLC initialization failed"
        exit 1
    fi

    # =========================================================================
    # Step 4: Generate spec via Claude
    # =========================================================================
    print_header "Step 4: Claude generates spec"

    if ! submit_build_and_wait "$PROJECT_NAME" "/spec-feature $FEATURE_SLUG" "Spec generation"; then
        print_error "Spec generation failed"
        exit 1
    fi

    # =========================================================================
    # Step 5: Approve spec via build
    # =========================================================================
    print_header "Step 5: Approve spec"

    if ! submit_build_and_wait "$PROJECT_NAME" \
        "Approve the spec artifact for feature $FEATURE_SLUG using: sdlc artifact approve $FEATURE_SLUG spec" \
        "Spec approval"; then
        print_warning "Spec approval may have failed, continuing..."
    fi

    # =========================================================================
    # Step 6: Generate design via Claude
    # =========================================================================
    print_header "Step 6: Claude generates design"

    if ! submit_build_and_wait "$PROJECT_NAME" "/design-feature $FEATURE_SLUG" "Design generation"; then
        print_error "Design generation failed"
        exit 1
    fi

    # =========================================================================
    # Step 7: Approve design via build
    # =========================================================================
    print_header "Step 7: Approve design"

    if ! submit_build_and_wait "$PROJECT_NAME" \
        "Approve the design artifact for feature $FEATURE_SLUG using: sdlc artifact approve $FEATURE_SLUG design" \
        "Design approval"; then
        print_warning "Design approval may have failed, continuing..."
    fi

    # =========================================================================
    # Step 8: Break down into tasks via Claude
    # =========================================================================
    print_header "Step 8: Claude breaks down into tasks"

    if ! submit_build_and_wait "$PROJECT_NAME" "/breakdown-feature $FEATURE_SLUG" "Task breakdown"; then
        print_error "Task breakdown failed"
        exit 1
    fi

    # =========================================================================
    # Step 9: Approve tasks via build
    # =========================================================================
    print_header "Step 9: Approve tasks"

    if ! submit_build_and_wait "$PROJECT_NAME" \
        "Approve the tasks artifact for feature $FEATURE_SLUG using: sdlc artifact approve $FEATURE_SLUG tasks" \
        "Tasks approval"; then
        print_warning "Tasks approval may have failed, continuing..."
    fi

    # =========================================================================
    # Step 10: Implement first task via Claude
    # =========================================================================
    print_header "Step 10: Claude implements first task"

    # First task is typically T1
    local first_task_id="T1"
    echo "  First task ID: $first_task_id"

    if ! submit_build_and_wait "$PROJECT_NAME" "/implement-task $FEATURE_SLUG $first_task_id" "Task implementation"; then
        print_error "Task implementation failed"
        exit 1
    fi

    # =========================================================================
    # Step 11: Verify artifacts exist
    # =========================================================================
    verify_artifacts "$PROJECT_NAME" "$FEATURE_SLUG"

    # =========================================================================
    # Summary
    # =========================================================================
    print_header "E2E Test Results"
    print_success "Feature development flow completed!"
    echo ""
    echo "  Project: $PROJECT_NAME"
    echo "  Feature: $FEATURE_SLUG"
    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"
    echo ""
    echo "Workflow completed:"
    echo "  1. Project skeleton created"
    echo "  2. Service component added"
    echo "  3. SDLC initialized + feature created (via build)"
    echo "  4. Claude generated spec"
    echo "  5. Spec approved"
    echo "  6. Claude generated design"
    echo "  7. Design approved"
    echo "  8. Claude broke down into tasks"
    echo "  9. Tasks approved"
    echo "  10. Claude implemented first task"
    echo ""
    echo "View the feature artifacts at:"
    echo "  https://git.threesix.ai/$(get_git_owner)/$PROJECT_NAME/src/branch/main/.sdlc/features/$FEATURE_SLUG"
}

# Show status
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 recent builds
    print_header "Recent Builds"
    api_call GET "/projects/$PROJECT_NAME/builds?limit=10" | jq '.data.builds[:10] // .builds[:10] // []'
    echo ""

    # Note about SDLC status
    echo "Note: SDLC status is stored in the git repo at .sdlc/"
    echo "View at: https://git.threesix.ai/$(get_git_owner)/$PROJECT_NAME/src/branch/main/.sdlc"
}

# Teardown
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."
}

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