package cluster

import (
	"context"

	"github.com/tidbcloud/tiinf/monitor/tilog"
	"go.uber.org/zap"
	"google.golang.org/protobuf/encoding/protojson"

	openapidedicatedv1beta1 "github.com/tidbcloud/tidb-management-service/api/spec/tidb_cloud_open_api/dedicated/v1beta1"
	"github.com/tidbcloud/tidb-management-service/tidb-mgmt-service/app/bff/orchestrator"
)

const (
	OpenAPIScaleAction           orchestrator.ActionName = "open_api_scale_action"
	OpenAPICreateTiDBGroupAction orchestrator.ActionName = "open_api_create_node_group"
	OpenAPIDeleteTiDBGroupAction orchestrator.ActionName = "open_api_delete_node_group"
	OpenAPIUpdateTiDBGroupAction orchestrator.ActionName = "open_api_update_node_group"
)

func RegisterActions(
	openAPIDedicatedClusterServer openapidedicatedv1beta1.ClusterServiceServer,
	openAPITiDBGroupServer openapidedicatedv1beta1.TidbNodeGroupServiceServer,
) []*orchestrator.OpenAPIAction {
	actions := []*orchestrator.OpenAPIAction{
		orchestrator.NewOpenAPIAction(OpenAPIScaleAction, func(ctx context.Context, message string) error {
			var request openapidedicatedv1beta1.UpdateClusterRequest
			if err := protojson.Unmarshal([]byte(message), &request); err != nil {
				tilog.Error(ctx, "unmarshal request body failed", zap.Error(err))
				return err
			}
			_, err := openAPIDedicatedClusterServer.UpdateCluster(ctx, &request)
			return err
		}),
		orchestrator.NewOpenAPIAction(OpenAPICreateTiDBGroupAction, func(ctx context.Context, message string) error {
			var request openapidedicatedv1beta1.CreateTidbNodeGroupRequest
			if err := protojson.Unmarshal([]byte(message), &request); err != nil {
				tilog.Error(ctx, "unmarshal request body failed", zap.Error(err))
				return err
			}

			_, err := openAPITiDBGroupServer.CreateTidbNodeGroup(ctx, &request)
			return err
		}),

		orchestrator.NewOpenAPIAction(OpenAPIDeleteTiDBGroupAction, func(ctx context.Context, message string) error {
			var request openapidedicatedv1beta1.DeleteTidbNodeGroupRequest
			if err := protojson.Unmarshal([]byte(message), &request); err != nil {
				tilog.Error(ctx, "unmarshal request body failed", zap.Error(err))
				return err
			}
			_, err := openAPITiDBGroupServer.DeleteTidbNodeGroup(ctx, &request)
			return err
		}),

		orchestrator.NewOpenAPIAction(OpenAPIUpdateTiDBGroupAction, func(ctx context.Context, message string) error {
			var request openapidedicatedv1beta1.UpdateTidbNodeGroupRequest
			if err := protojson.Unmarshal([]byte(message), &request); err != nil {
				tilog.Error(ctx, "unmarshal request body failed", zap.Error(err))
				return err
			}
			_, err := openAPITiDBGroupServer.UpdateTidbNodeGroup(ctx, &request)
			return err
		}),
	}

	return actions
}
