package suite

import (
	"context"

	"code.justin.tv/eventbus/controlplane/e2e/internal/httpserver"

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

var _ Runner = &IAMRoleDeleteTestSuite{}

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

func NewCreateIAMRoleAPI(suiteName string) (Runner, error) {
	defaultTest, err := NewDefaultTestSuite(suiteName)
	if err != nil {
		return nil, err
	}
	return &CreateIAMRoleAPITestSuite{
		DefaultTestSuite: defaultTest,
	}, nil
}

func (s *CreateIAMRoleAPITestSuite) Test(ctx context.Context) {
	ctx = e2eutil.AppendTestPath(ctx, s.TestName())
	s.DefaultTestSuite.Test(ctx)

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

	service, err := httpserver.Service("666")
	if err != nil {
		s.Error(ctx, "error fetching service", err)
		return
	}

	if len(service.GetIamRoles()) != 0 {
		s.Error(ctx, "0 IAM roles", nil)
		return
	}

	arn := "arn:aws:iam::567312298267:role/e2e-publisher-role"
	label := "created-iam-role"

	resp, err := c.CreateIAMRole(ctx, &rpc.CreateIAMRoleReq{
		ServiceId: service.GetId(),
		IamRole: &rpc.IAMRole{
			Arn:   arn,
			Label: label,
		},
	})
	if err != nil {
		s.Error(ctx, "could not create iam role", err)
		return
	}

	if resp.GetIamRole().GetId() == "" {
		s.Error(ctx, "expected returned iam role to contain an id", err)
		return
	}

	service, err = httpserver.Service("666")
	if err != nil {
		s.Error(ctx, "error fetching service", err)
		return
	}

	if len(service.GetIamRoles()) != 1 || service.GetIamRoles()[0].GetArn() != arn || service.GetIamRoles()[0].GetLabel() != label {
		s.Error(ctx, "iam role not correct after creation", nil)
		return
	}

	updateResp, err := c.UpdateIAMRoleLabel(ctx, &rpc.UpdateIAMRoleLabelReq{
		Arn:   arn,
		Label: "the-new-label",
	})
	if err != nil {
		s.Error(ctx, "could not update label", err)
		return
	} else if updateResp == nil || updateResp.GetLabel() != "the-new-label" {
		s.Error(ctx, "update label operation failed", nil)
		return
	}

	service, err = httpserver.Service("666")
	if err != nil {
		s.Error(ctx, "error fetching service after updating role label", err)
		return
	}

	if len(service.GetIamRoles()) != 1 && service.GetIamRoles()[0].GetLabel() != "the-new-label" {
		s.Error(ctx, "expected updated iam role label", nil)
		return
	}
}

func (s *CreateIAMRoleAPITestSuite) TestName() string {
	return "CreateIAMRoleAPITestSuite"
}
