package agent

import (
	"net/url"

	"buf.build/go/protovalidate"
	"github.com/google/cel-go/cel"
	"gitlab.com/gitlab-org/cluster-integration/gitlab-agent/v18/internal/module/kubernetes_api/rpc"
	"k8s.io/cli-runtime/pkg/resource"
	"k8s.io/client-go/rest"
)

type server struct {
	rpc.UnsafeKubernetesApiServer
	resEnv     *cel.Env
	objEnv     *cel.Env
	validator  protovalidate.Validator
	restConfig *rest.Config
	newBuilder func() *resource.Builder
	baseURL    *url.URL
	userAgent  string
	version    string
	via        string
}

func newServer(v protovalidate.Validator, restConfig *rest.Config, newBuilder func() *resource.Builder, baseURL *url.URL, userAgent, version string) (*server, error) {
	env, err := cel.NewEnv(
		cel.EagerlyValidateDeclarations(true),
		cel.Variable("group", cel.StringType),
		cel.Variable("version", cel.StringType),
		cel.Variable("resource", cel.StringType),
	)
	if err != nil {
		return nil, err
	}
	resEnv, err := env.Extend(
		cel.Variable("namespaced", cel.BoolType),
	)
	if err != nil {
		return nil, err
	}
	mapStrStr := cel.MapType(cel.StringType, cel.StringType)
	objEnv, err := env.Extend(
		cel.Variable("namespace", cel.StringType),
		cel.Variable("name", cel.StringType),
		cel.Variable("labels", mapStrStr),
		cel.Variable("annotations", mapStrStr),
		cel.Variable("name", cel.StringType),
		cel.Variable("obj", cel.MapType(cel.StringType, cel.DynType)),
	)
	if err != nil {
		return nil, err
	}
	return &server{
		resEnv:     resEnv,
		objEnv:     objEnv,
		validator:  v,
		restConfig: restConfig,
		newBuilder: newBuilder,
		baseURL:    baseURL,
		userAgent:  userAgent,
		version:    version,
		via:        "gRPC/1.0 " + userAgent,
	}, nil
}
