package console

import (
	"context"
	"testing"

	"github.com/stretchr/testify/mock"
	"github.com/stretchr/testify/require"
	sink_endpoint_mock "github.com/tidbcloud/dataflow-service-ng/app/models/sink_endpoint/mock"
	dataflow "github.com/tidbcloud/dataflow-service-ng/idl/pbgen/proto/consoleapi"
	grpcli_mock "github.com/tidbcloud/dataflow-service-ng/pkg/grpc/grpcli/mock"
	"github.com/tidbcloud/pkgv2/bizerr"
	mgmt "github.com/tidbcloud/tidb-management-service/api/spec/tidb_mgmt_service/v1"
)

func TestSinkEndpointWritesRequireAuthenticatedActor(t *testing.T) {
	tests := map[string]func(SinkEndpointController) error{
		"create": func(controller SinkEndpointController) error {
			_, err := controller.CreateSinkEndpoint(
				context.Background(),
				&dataflow.CreateSinkEndpointRequest{
					ClusterId: 1,
					SinkEndpoint: &dataflow.SinkEndpoint{
						EndpointName:        "endpoint",
						EndpointServiceName: "service",
					},
				},
			)
			return err
		},
		"delete": func(controller SinkEndpointController) error {
			_, err := controller.DeleteSinkEndpoint(
				context.Background(),
				&dataflow.DeleteSinkEndpointRequest{ClusterId: 1, SinkEndpointId: 2},
			)
			return err
		},
	}

	for name, run := range tests {
		t.Run(name, func(t *testing.T) {
			model := sink_endpoint_mock.NewSinkEndpointModel(t)
			mgmtCli := grpcli_mock.NewMgmtSvcGrpcClient(t)
			mgmtCli.On("GetClusterByID", mock.Anything, uint64(1)).
				Return(&mgmt.Cluster{ClusterId: 1, ProjectId: 2, OrganizationId: 3}, nil).
				Once()
			controller := NewSinkEndpointController(model, nil, mgmtCli)

			err := run(controller)
			require.Error(t, err)
			bizErr, ok := err.(bizerr.BizError)
			require.True(t, ok)
			require.Equal(t, bizerr.ErrCodePermission, bizErr.RawErrCode())
			model.AssertNotCalled(t, "CreateSinkEndpoint", mock.Anything, mock.Anything)
			model.AssertNotCalled(t, "QuerySinkEndpoint", mock.Anything, mock.Anything)
			model.AssertNotCalled(t, "DeleteSinkEndpoint", mock.Anything, mock.Anything)
		})
	}
}
