// Async webhook worker: trigger with the webhook token, then export with the API token.
//
// Documented at https://appcd-dev.github.io/stackgen-sdk/code-samples/async-webhook-worker/
//
//	export STACKGEN_URL=https://app.stackgen.com
//	export STACKGEN_TOKEN=stackgen_…
//	export STACKGEN_WORKSPACE_ID=<workspace-uuid>
//	export STACKGEN_WEBHOOK_TOKEN=sg_aios_…
//	go run ./examples/go/recipes/webhook-async-worker.go --start-only
//	go run ./examples/go/recipes/webhook-async-worker.go
package main

import (
	"context"
	"encoding/json"
	"flag"
	"fmt"
	"os"
	"strings"

	stackgen "github.com/appcd-dev/stackgen-sdk/clients/go"
)

func envOr(keys ...string) string {
	for _, key := range keys {
		if v := strings.TrimSpace(os.Getenv(key)); v != "" {
			return v
		}
	}
	return ""
}

func text(m map[string]any, keys ...string) string {
	for _, key := range keys {
		if v, ok := m[key].(string); ok && strings.TrimSpace(v) != "" {
			return strings.TrimSpace(v)
		}
	}
	return ""
}

func main() {
	query := flag.String("query", "Investigate the checkout CPU alert in prod", "Alert text")
	correlationID := flag.String("correlation-id", "corr-123", "Correlation id")
	timeoutSeconds := flag.Int("timeout-seconds", 1800, "Overall timeout")
	pollInterval := flag.Int("poll-interval-seconds", 5, "Poll interval")
	startOnly := flag.Bool("start-only", false, "Trigger and exit before waiting for a session")
	flag.Parse()

	base := envOr("STACKGEN_URL", "STACKGEN_BASE_URL")
	token := envOr("STACKGEN_TOKEN", "STACKGEN_API_TOKEN")
	org := envOr("STACKGEN_WORKSPACE_ID", "STACKGEN_PROJECT", "STACKGEN_PROJECT_ID")
	webhook := envOr("STACKGEN_WEBHOOK_TOKEN", "WEBHOOK_TOKEN")
	if base == "" || token == "" || org == "" || webhook == "" {
		fmt.Fprintln(os.Stderr, "set STACKGEN_URL, STACKGEN_TOKEN, STACKGEN_WORKSPACE_ID, and STACKGEN_WEBHOOK_TOKEN")
		os.Exit(2)
	}
	client, err := stackgen.NewClient(stackgen.Config{
		BaseURL:             base,
		APIToken:            token,
		WorkspaceID:         org,
		WebhookToken:        webhook,
		TimeoutSeconds:      *timeoutSeconds,
		PollIntervalSeconds: *pollInterval,
	})
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	ctx := context.Background()
	payload, _ := json.Marshal(map[string]string{
		"query":          *query,
		"message":        *query,
		"correlation_id": *correlationID,
	})
	triggered, err := client.Aiden.TriggerWebhook(ctx, string(payload))
	if err != nil {
		fmt.Fprintln(os.Stderr, "error:", err)
		os.Exit(1)
	}
	raw, _ := json.MarshalIndent(triggered, "", "  ")
	fmt.Println("trigger:", string(raw))
	if *startOnly {
		return
	}
	sessionID := text(triggered, "session_id", "sessionId")
	if sessionID == "" {
		webhookID := text(triggered, "webhook_id", "webhookId")
		invocationID := text(triggered, "invocation_id", "invocationId")
		if webhookID == "" || invocationID == "" {
			fmt.Fprintln(os.Stderr, "error: trigger missing webhook_id/invocation_id and session_id")
			os.Exit(1)
		}
		sessionID, err = client.Aiden.WaitForWebhookSession(ctx, webhookID, invocationID, text(triggered, "run_id", "id"), nil)
		if err != nil {
			fmt.Fprintln(os.Stderr, "error:", err)
			os.Exit(1)
		}
		fmt.Fprintf(os.Stderr, "resolved session_id=%s\n", sessionID)
	}
	detail, err := client.Aiden.GetSession(ctx, sessionID)
	if err != nil {
		fmt.Fprintln(os.Stderr, "error:", err)
		os.Exit(1)
	}
	raw, _ = json.MarshalIndent(detail, "", "  ")
	fmt.Println("get_session:", string(raw))
	exported, err := client.Aiden.ExportSession(ctx, sessionID, "report", "json")
	if err != nil {
		fmt.Fprintln(os.Stderr, "error:", err)
		os.Exit(1)
	}
	raw, _ = json.MarshalIndent(exported, "", "  ")
	fmt.Println("export:", string(raw))
}
