package manual

import (
	"context"
	"encoding/json"
	"strings"
	"testing"

	"github.com/alexei/tinyforge/internal/workload/plugin"
)

func TestValidate(t *testing.T) {
	tr := &trigger{}
	cases := []struct {
		name    string
		cfg     json.RawMessage
		wantErr bool
	}{
		{"empty body accepted", nil, false},
		{"empty object accepted", json.RawMessage(`{}`), false},
		{"valid small object accepted", json.RawMessage(`{"note":"hello"}`), false},
		{"invalid json rejected", json.RawMessage(`not json`), true},
		{"oversize rejected", json.RawMessage(`{"big":"` + strings.Repeat("x", 1100) + `"}`), true},
	}
	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			err := tr.Validate(tc.cfg)
			if (err != nil) != tc.wantErr {
				t.Fatalf("Validate(%s) err=%v want err=%v", tc.name, err, tc.wantErr)
			}
		})
	}
}

func TestMatch(t *testing.T) {
	tr := &trigger{}
	wl := plugin.Workload{ID: "wkl-1"}

	t.Run("wrong kind ignored", func(t *testing.T) {
		evt := plugin.InboundEvent{Kind: "image-push"}
		intent, err := tr.Match(context.Background(), plugin.Deps{}, wl, evt)
		if err != nil || intent != nil {
			t.Fatalf("expected nil intent, got intent=%v err=%v", intent, err)
		}
	})

	t.Run("manual fires with actor + note", func(t *testing.T) {
		evt := plugin.InboundEvent{
			Kind:   "manual",
			Manual: &plugin.ManualEvent{Actor: "alice", Reference: "v1.0.0", Note: "rollback"},
		}
		intent, err := tr.Match(context.Background(), plugin.Deps{}, wl, evt)
		if err != nil {
			t.Fatalf("unexpected error: %v", err)
		}
		if intent == nil {
			t.Fatal("expected non-nil intent")
		}
		if intent.TriggeredBy != "alice" {
			t.Errorf("TriggeredBy = %q, want alice", intent.TriggeredBy)
		}
		if intent.Reference != "v1.0.0" {
			t.Errorf("Reference = %q, want v1.0.0", intent.Reference)
		}
		if intent.Metadata["note"] != "rollback" {
			t.Errorf("note metadata = %q, want rollback", intent.Metadata["note"])
		}
	})

	t.Run("missing actor falls back", func(t *testing.T) {
		evt := plugin.InboundEvent{
			Kind:   "manual",
			Manual: &plugin.ManualEvent{Reference: "v2"},
		}
		intent, err := tr.Match(context.Background(), plugin.Deps{}, wl, evt)
		if err != nil {
			t.Fatalf("unexpected error: %v", err)
		}
		if intent.TriggeredBy != "manual" {
			t.Errorf("TriggeredBy = %q, want manual", intent.TriggeredBy)
		}
	})
}
