package suite

import (
	"context"

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

var _ Runner = &FeatureFlagTestSuite{}

type FeatureFlagTestSuite struct {
	*DefaultTestSuite // Use the default suite as ground work
}

func NewFeatureFlagTestSuite(suiteName string) (Runner, error) {
	// Base setup, testing, and cleaning procedures
	defaultTest, err := NewDefaultTestSuite(suiteName)
	if err != nil {
		return nil, err
	}
	// Wrap the basic tooling with some extra tests
	return &FeatureFlagTestSuite{
		DefaultTestSuite: defaultTest,
	}, nil
}

// Test includes the default testing, plus an extra test to publish
// an event to the stream
func (f *FeatureFlagTestSuite) Test(ctx context.Context) {
	ctx = e2eutil.AppendTestPath(ctx, f.TestName())
	f.DefaultTestSuite.Test(ctx)

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

	flag := f.FeatureFlags[0]
	flagName := e2eutil.Suffix(flag.Name, e2eutil.JobID(ctx))

	f.Log(ctx, "toggling feature flag "+flagName)

	// Enable
	_, err := c.Enable(ctx, &rpc.EnableReq{
		Name: flagName,
	})
	if err != nil {
		f.Error(ctx, "could not enable feature flag", err)
		return
	}

	// Verify enable
	isEnabledResp, err := c.IsEnabled(ctx, &rpc.IsEnabledReq{
		Name: flagName,
	})
	if err != nil {
		f.Error(ctx, "could not determine if flag is enabled", err)
		return
	} else if !isEnabledResp.GetIsEnabled() {
		f.Error(ctx, "flag enable mismatch, expecting true, got false", nil)
		return
	}

	// Disable
	_, err = c.Disable(ctx, &rpc.DisableReq{
		Name: flagName,
	})
	if err != nil {
		f.Error(ctx, "could not disable feature flag", err)
		return
	}

	// Verify disable
	isEnabledResp, err = c.IsEnabled(ctx, &rpc.IsEnabledReq{
		Name: flagName,
	})
	if err != nil {
		f.Error(ctx, "could not determine if flag is disabled", err)
		return
	} else if isEnabledResp.GetIsEnabled() {
		f.Error(ctx, "flag enable mismatch, expecting false, got true", nil)
		return
	}
}

func (f *FeatureFlagTestSuite) TestName() string {
	return "FeatureFlagTestSuite"
}
