#!/bin/bash
set -euo pipefail

# Scaffold Validation E2E Test Script
# Tests the composable monorepo scaffold creation:
#   1. Create composable project with skeleton
#   2. Add service component
#   3. Add app-nextjs component
#   4. Verify chassis patterns are available
#   5. Verify design system packages exist
#   6. Test auth integration
#   7. Verify CI pipeline
#
# NOTE: This tests scaffold creation and patterns, NOT feature development.
# For feature development E2E tests, see feature-dev-test.sh instead.
#
# Usage: ./cookbooks/scripts/scaffold-test.sh <command> <project-name>
# Commands: run, status, verify-patterns, 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 full stack and verify patterns"
    echo "  status           - Check project status"
    echo "  verify-patterns  - Verify chassis and design system patterns exist"
    echo "  teardown         - Delete the project"
    exit 1
fi

# Verify chassis patterns in the created project
verify_chassis_patterns() {
    local project_id="$1"
    local git_owner
    git_owner=$(get_git_owner)

    print_header "Verifying Chassis Patterns"

    # Check pkg/httperror exists
    echo "Checking pkg/httperror..."
    local httperror_check
    httperror_check=$(curl -s "https://git.threesix.ai/api/v1/repos/$git_owner/$project_id/contents/pkg/httperror/error.go" \
        -H "Authorization: token ${GITEA_TOKEN:-}" 2>/dev/null | jq -r '.name // "not found"')

    if [[ "$httperror_check" == "error.go" ]]; then
        print_success "pkg/httperror/error.go exists"
    else
        print_warning "pkg/httperror/error.go not found (may be named differently)"
    fi

    # Check pkg/app/handler.go (Wrap pattern)
    echo "Checking pkg/app/handler.go (Wrap pattern)..."
    local handler_check
    handler_check=$(curl -s "https://git.threesix.ai/api/v1/repos/$git_owner/$project_id/contents/pkg/app/handler.go" \
        -H "Authorization: token ${GITEA_TOKEN:-}" 2>/dev/null | jq -r '.name // "not found"')

    if [[ "$handler_check" == "handler.go" ]]; then
        print_success "pkg/app/handler.go exists (Wrap pattern)"
    else
        print_warning "pkg/app/handler.go not found"
    fi

    # Check pkg/app/bind.go
    echo "Checking pkg/app/bind.go..."
    local bind_check
    bind_check=$(curl -s "https://git.threesix.ai/api/v1/repos/$git_owner/$project_id/contents/pkg/app/bind.go" \
        -H "Authorization: token ${GITEA_TOKEN:-}" 2>/dev/null | jq -r '.name // "not found"')

    if [[ "$bind_check" == "bind.go" ]]; then
        print_success "pkg/app/bind.go exists (Bind pattern)"
    else
        print_warning "pkg/app/bind.go not found"
    fi

    # Check pkg/app/health.go
    echo "Checking pkg/app/health.go..."
    local health_check
    health_check=$(curl -s "https://git.threesix.ai/api/v1/repos/$git_owner/$project_id/contents/pkg/app/health.go" \
        -H "Authorization: token ${GITEA_TOKEN:-}" 2>/dev/null | jq -r '.name // "not found"')

    if [[ "$health_check" == "health.go" ]]; then
        print_success "pkg/app/health.go exists (Health probes)"
    else
        print_warning "pkg/app/health.go not found"
    fi

    # Check pkg/auth exists
    echo "Checking pkg/auth..."
    local auth_check
    auth_check=$(curl -s "https://git.threesix.ai/api/v1/repos/$git_owner/$project_id/contents/pkg/auth" \
        -H "Authorization: token ${GITEA_TOKEN:-}" 2>/dev/null | jq -r 'if type == "array" then "directory" else "not found" end')

    if [[ "$auth_check" == "directory" ]]; then
        print_success "pkg/auth/ directory exists"
    else
        print_warning "pkg/auth/ not found"
    fi

    # Check pkg/chassis exists
    echo "Checking pkg/chassis..."
    local chassis_check
    chassis_check=$(curl -s "https://git.threesix.ai/api/v1/repos/$git_owner/$project_id/contents/pkg/chassis/chassis.go" \
        -H "Authorization: token ${GITEA_TOKEN:-}" 2>/dev/null | jq -r '.name // "not found"')

    if [[ "$chassis_check" == "chassis.go" ]]; then
        print_success "pkg/chassis/chassis.go exists (facade)"
    else
        print_warning "pkg/chassis/chassis.go not found"
    fi

    # Check pkg/openapi exists
    echo "Checking pkg/openapi..."
    local openapi_check
    openapi_check=$(curl -s "https://git.threesix.ai/api/v1/repos/$git_owner/$project_id/contents/pkg/openapi" \
        -H "Authorization: token ${GITEA_TOKEN:-}" 2>/dev/null | jq -r 'if type == "array" then "directory" else "not found" end')

    if [[ "$openapi_check" == "directory" ]]; then
        print_success "pkg/openapi/ directory exists (spec builder + docs)"
    else
        print_warning "pkg/openapi/ not found"
    fi
}

# Verify design system packages
verify_design_system() {
    local project_id="$1"
    local git_owner
    git_owner=$(get_git_owner)

    print_header "Verifying Design System Packages"

    # Check packages/ui exists
    echo "Checking packages/ui..."
    local ui_check
    ui_check=$(curl -s "https://git.threesix.ai/api/v1/repos/$git_owner/$project_id/contents/packages/ui/package.json" \
        -H "Authorization: token ${GITEA_TOKEN:-}" 2>/dev/null | jq -r '.name // "not found"')

    if [[ "$ui_check" == "package.json" ]]; then
        print_success "packages/ui exists"
    else
        print_warning "packages/ui not found"
    fi

    # Check packages/layout exists
    echo "Checking packages/layout..."
    local layout_check
    layout_check=$(curl -s "https://git.threesix.ai/api/v1/repos/$git_owner/$project_id/contents/packages/layout/package.json" \
        -H "Authorization: token ${GITEA_TOKEN:-}" 2>/dev/null | jq -r '.name // "not found"')

    if [[ "$layout_check" == "package.json" ]]; then
        print_success "packages/layout exists"
    else
        print_warning "packages/layout not found"
    fi

    # Check packages/auth exists
    echo "Checking packages/auth..."
    local auth_check
    auth_check=$(curl -s "https://git.threesix.ai/api/v1/repos/$git_owner/$project_id/contents/packages/auth/package.json" \
        -H "Authorization: token ${GITEA_TOKEN:-}" 2>/dev/null | jq -r '.name // "not found"')

    if [[ "$auth_check" == "package.json" ]]; then
        print_success "packages/auth exists"
    else
        print_warning "packages/auth not found"
    fi

    # Check packages/api-client exists
    echo "Checking packages/api-client..."
    local client_check
    client_check=$(curl -s "https://git.threesix.ai/api/v1/repos/$git_owner/$project_id/contents/packages/api-client/package.json" \
        -H "Authorization: token ${GITEA_TOKEN:-}" 2>/dev/null | jq -r '.name // "not found"')

    if [[ "$client_check" == "package.json" ]]; then
        print_success "packages/api-client exists"
    else
        print_warning "packages/api-client not found"
    fi
}

# Verify service component uses chassis patterns
verify_service_patterns() {
    local project_id="$1"
    local git_owner
    git_owner=$(get_git_owner)

    print_header "Verifying Service Component"

    # Check services/api exists
    echo "Checking services/api..."
    local svc_check
    svc_check=$(curl -s "https://git.threesix.ai/api/v1/repos/$git_owner/$project_id/contents/services/api/cmd/server/main.go" \
        -H "Authorization: token ${GITEA_TOKEN:-}" 2>/dev/null | jq -r '.name // "not found"')

    if [[ "$svc_check" == "main.go" ]]; then
        print_success "services/api component exists"
    else
        print_warning "services/api not found"
    fi

    # Check services/api/internal/api/routes.go exists
    echo "Checking routes.go..."
    local routes_check
    routes_check=$(curl -s "https://git.threesix.ai/api/v1/repos/$git_owner/$project_id/contents/services/api/internal/api/routes.go" \
        -H "Authorization: token ${GITEA_TOKEN:-}" 2>/dev/null | jq -r '.name // "not found"')

    if [[ "$routes_check" == "routes.go" ]]; then
        print_success "services/api/internal/api/routes.go exists"
    else
        print_warning "routes.go not found"
    fi

    # Check services/api/internal/api/spec.go exists (OpenAPI)
    echo "Checking spec.go (OpenAPI)..."
    local spec_check
    spec_check=$(curl -s "https://git.threesix.ai/api/v1/repos/$git_owner/$project_id/contents/services/api/internal/api/spec.go" \
        -H "Authorization: token ${GITEA_TOKEN:-}" 2>/dev/null | jq -r '.name // "not found"')

    if [[ "$spec_check" == "spec.go" ]]; then
        print_success "services/api/internal/api/spec.go exists (OpenAPI spec)"
    else
        print_warning "spec.go not found"
    fi

    # Check services/api/internal/api/handlers/example_test.go exists
    echo "Checking example_test.go..."
    local test_check
    test_check=$(curl -s "https://git.threesix.ai/api/v1/repos/$git_owner/$project_id/contents/services/api/internal/api/handlers/example_test.go" \
        -H "Authorization: token ${GITEA_TOKEN:-}" 2>/dev/null | jq -r '.name // "not found"')

    if [[ "$test_check" == "example_test.go" ]]; then
        print_success "services/api/internal/api/handlers/example_test.go exists"
    else
        print_warning "example_test.go not found"
    fi
}

# Verify app-nextjs component
verify_nextjs_app() {
    local project_id="$1"
    local git_owner
    git_owner=$(get_git_owner)

    print_header "Verifying Next.js App Component"

    # Check apps/dashboard exists
    echo "Checking apps/dashboard..."
    local app_check
    app_check=$(curl -s "https://git.threesix.ai/api/v1/repos/$git_owner/$project_id/contents/apps/dashboard/package.json" \
        -H "Authorization: token ${GITEA_TOKEN:-}" 2>/dev/null | jq -r '.name // "not found"')

    if [[ "$app_check" == "package.json" ]]; then
        print_success "apps/dashboard exists"
    else
        print_warning "apps/dashboard not found"
    fi

    # Check App Router structure
    echo "Checking App Router structure..."
    local layout_check
    layout_check=$(curl -s "https://git.threesix.ai/api/v1/repos/$git_owner/$project_id/contents/apps/dashboard/src/app/layout.tsx" \
        -H "Authorization: token ${GITEA_TOKEN:-}" 2>/dev/null | jq -r '.name // "not found"')

    if [[ "$layout_check" == "layout.tsx" ]]; then
        print_success "App Router layout.tsx exists"
    else
        print_warning "App Router layout.tsx not found"
    fi

    # Check dashboard route group
    echo "Checking (dashboard) route group..."
    local dashboard_check
    dashboard_check=$(curl -s "https://git.threesix.ai/api/v1/repos/$git_owner/$project_id/contents/apps/dashboard/src/app/(dashboard)/layout.tsx" \
        -H "Authorization: token ${GITEA_TOKEN:-}" 2>/dev/null | jq -r '.name // "not found"')

    if [[ "$dashboard_check" == "layout.tsx" ]]; then
        print_success "(dashboard) route group exists"
    else
        print_warning "(dashboard) route group not found"
    fi
}

# Add a component and verify
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

    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 "Feature Development 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 "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 backend service
    print_header "Step 2: Adding backend service"
    if ! add_component "service" "api"; then
        exit 1
    fi

    # Step 3: Add Next.js dashboard
    print_header "Step 3: Adding Next.js dashboard"
    if ! add_component "app-nextjs" "dashboard"; 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 initial commit to propagate
    print_header "Step 5: Waiting for git to sync..."
    sleep 10

    # Step 6: Verify patterns
    verify_chassis_patterns "$PROJECT_NAME"
    verify_design_system "$PROJECT_NAME"
    verify_service_patterns "$PROJECT_NAME"
    verify_nextjs_app "$PROJECT_NAME"

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

    # Step 8: Wait for site
    print_header "Step 8: Verifying site is accessible"
    if ! wait_for_site "$domain" 30 5 "$PROJECT_NAME"; then
        print_warning "Site not yet accessible (may still be deploying)"
    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/$(get_git_owner)/$PROJECT_NAME"
    echo "CI: https://ci.threesix.ai/$(get_git_owner)/$PROJECT_NAME"
    echo ""
    echo "Next steps:"
    echo "  1. Clone the repo and start developing features"
    echo "  2. Use pkg/httperror, pkg/app for chassis patterns"
    echo "  3. Use packages/ui, packages/layout for design system"
    echo "  4. Use packages/auth for authentication"
    echo "  5. Run ./scripts/generate-client.sh after OpenAPI changes"
}

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] // .'
}

verify_patterns() {
    print_header "Verifying Patterns: $PROJECT_NAME"

    verify_chassis_patterns "$PROJECT_NAME"
    verify_design_system "$PROJECT_NAME"
    verify_service_patterns "$PROJECT_NAME"
    verify_nextjs_app "$PROJECT_NAME"

    print_header "Verification Complete"
}

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

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