package resource

import (
	"context"
	"fmt"

	"github.com/pkg/errors"

	"code.justin.tv/eventbus/controlplane/e2e/internal/e2eutil"
	"code.justin.tv/eventbus/controlplane/e2e/internal/expected"
	"code.justin.tv/eventbus/controlplane/e2e/internal/report"
	"code.justin.tv/eventbus/controlplane/e2e/internal/test"
	"code.justin.tv/eventbus/controlplane/rpc"
)

var _ test.Runner = &FeatureFlag{}

var ErrFeatureFlagNotFound = errors.New("could not find feature flag")

type FeatureFlag struct {
	test.TestRunner

	Name      string `json:"name"`
	IsEnabled bool   `json:"is_enabled"`
}

func (f *FeatureFlag) TestName() string {
	return fmt.Sprintf("FeatureFlag{%s,%t}", f.Name, f.IsEnabled)
}

func (f *FeatureFlag) Setup(ctx context.Context) report.Error {
	ctx = e2eutil.AppendTestPath(ctx, f.TestName())
	f.Log(ctx, "Creating feature flag")

	c := rpc.NewFeatureFlagsProtobufClient(expected.TwirpEndpoint, e2eutil.HTTPClientWithLDAP())
	flagName := e2eutil.Suffix(f.Name, e2eutil.JobID(ctx))

	f.Log(ctx, "Creating feature flag "+flagName)
	_, err := c.Create(ctx, &rpc.CreateFeatureFlagsReq{
		FeatureFlag: &rpc.FeatureFlag{
			Name:      flagName,
			IsEnabled: f.IsEnabled,
		},
	})
	if err != nil {
		return report.ErrorFromContext(ctx, "could not create feature flag", err)
	}

	return nil
}

func (f *FeatureFlag) Test(ctx context.Context) {
	ctx = e2eutil.AppendTestPath(ctx, f.TestName())
	f.Log(ctx, "Beginning feature flag tests")

	c := rpc.NewFeatureFlagsProtobufClient(expected.TwirpEndpoint, e2eutil.HTTPClientWithLDAP())

	resp, err := c.IsEnabled(ctx, &rpc.IsEnabledReq{
		Name: e2eutil.Suffix(f.Name, e2eutil.JobID(ctx)),
	})
	if err != nil {
		f.Error(ctx, "could not fetch feature flag", err)
		return
	}

	if resp.GetIsEnabled() != f.IsEnabled {
		f.Error(ctx, fmt.Sprintf("feature flag is_enabled mismatch, got %t but expected %t", f.IsEnabled, resp.GetIsEnabled()), nil)
	}
}

func (f *FeatureFlag) Clean(ctx context.Context) []report.Error { return nil }
