package deploy

import (
	"context"
	"errors"
	"testing"

	"github.com/stretchr/testify/assert"
	ctrl "sigs.k8s.io/controller-runtime"
)

type hookTracker struct {
	called   bool
	lastTask Task
}

func TestTaskWrapper(t *testing.T) {
	tests := []struct {
		name         string
		createResult Result
		postResult   Result
		wantHookCall bool
	}{
		{
			name:         "post create hook called when both succeed",
			createResult: Done(),
			postResult:   Done(),
			wantHookCall: true,
		},
		{
			name:         "post create hook not called when create has error",
			createResult: Error(errors.New("create-failed")),
			postResult:   Done(),
			wantHookCall: false,
		},
		{
			name:         "post create hook not called when post create has error",
			createResult: Done(),
			postResult:   Error(errors.New("post-failed")),
			wantHookCall: false,
		},
		{
			name:         "post create hook called when create has requeue-only error",
			createResult: Result{state: stateDone, err: NewRetriableError(ErrorRequeueOnly, ctrl.Result{Requeue: true})},
			postResult:   Done(),
			wantHookCall: true,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			var calls []string
			tracker := &hookTracker{}
			inner := &mockTask{name: "inner", calls: &calls, create: tt.createResult, postCreate: tt.postResult}
			w := NewTaskWrapper(inner, func(_ context.Context, task Task) {
				tracker.called = true
				tracker.lastTask = task
			})
			w.Create(context.Background())
			w.PostCreate(context.Background())
			assert.Equal(t, tt.wantHookCall, tracker.called)
			if tt.wantHookCall {
				assert.Equal(t, "inner", tracker.lastTask.Name())
			}
		})
	}
}
