package adminapigrpc

import (
	"context"
	"dataservices/commons/ginparser"
	adminapiv1beta1 "dataservices/idl/pbgen/proto/v1beta1"
	service "dataservices/internal/service/central"
	"fmt"

	"github.com/tidbcloud/dataservices/idl/pbgen/proto/dataapi"
	"github.com/tidbcloud/tiinf/errs"
)

type ApiSpecService struct {
	adminapiv1beta1.UnimplementedApiSpecServiceServer
}

func convertFormat(format adminapiv1beta1.GetApiSpecRequest_Format) string {
	switch format {
	case adminapiv1beta1.GetApiSpecRequest_JSON:
		return "json"
	case adminapiv1beta1.GetApiSpecRequest_YAML:
		return "yaml"
	default:
		return "json"
	}
}

func (s *ApiSpecService) GetApiSpec(ctx context.Context, req *adminapiv1beta1.GetApiSpecRequest) (*adminapiv1beta1.ApiSpec, error) {
	params := ginparser.ParseAdminApiPathParameters(ctx, req.Name)
	innerAppId, err := ginparser.GetRequestInnerAppIdGrpc(ctx)
	if err != nil {
		return nil, errs.NewBadRequest("invalid innerAppId", err)
	}
	_type, createdBy, err := ginparser.GetCreatedByFromGrpc(ctx)
	if err != nil {
		return nil, errs.NewBadRequest("invalid request public key", err)
	}
	err = service.AuthorizeOpenApiSpecification(ctx, innerAppId)
	if err != nil {
		return nil, err
	}
	cred := &dataapi.Credential{Type: _type, Key: createdBy, AccountId: createdBy}

	oas, err := service.GenerateOpenApiSpecification(
		ctx,
		innerAppId,
		cred,
		convertFormat(req.Format),
	)
	if err != nil {
		return nil, err
	}
	return &adminapiv1beta1.ApiSpec{
		Name:    fmt.Sprintf("dataApps/%s/apiSpec", params.ExternalAppId),
		Content: oas.Document,
	}, nil
}
