package resourcemanager

import (
	"context"
	"os"
	"testing"

	"github.com/tidbcloud/observability/pkg/common/metrics"

	vmv1 "github.com/VictoriaMetrics/operator/api/operator/v1beta1"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

	"github.com/tidbcloud/observability/pkg/common/constants"

	prometheusv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
	"github.com/tidbcloud/observability/pkg/common/configs"
	"github.com/tidbcloud/observability/pkg/common/structs"

	v1 "github.com/tidbcloud/observability/api/regionalserver/resourceworker/v1"

	corev1 "k8s.io/api/core/v1"
	"k8s.io/client-go/kubernetes/fake"
	"sigs.k8s.io/controller-runtime/pkg/client"
	fake2 "sigs.k8s.io/controller-runtime/pkg/client/fake"
)

var segmentServer configMapSegmentMgr
var fakeClient = fake.NewSimpleClientset(&corev1.ConfigMap{})

func TestMain(m *testing.M) {
	configs.Init(structs.ServiceInfo{
		Vendor: "aws",
		Region: "us-east-2",
	})
	metrics.SetupMetrics()

	segmentServer = configMapSegmentMgr{
		name:       constants.DataAccountSegmentConfigMap,
		retries:    10,
		keyStartId: constants.DataAccountKeyStartID,
		kubeClient: fakeClient,
		namespace:  constants.ObservabilityNamespace,
	}
	createSegmentConfigMap(context.TODO())
	v1.SchemeBuilder.Register(&prometheusv1.PrometheusRule{}, &prometheusv1.PrometheusRuleList{}, &vmv1.VMRuleList{}, &vmv1.VMRule{})
	clusterRoleBindingRW = clusterRoleBindingReaderWriter{
		kubeClient: fakeClient,
	}

	schema, err := v1.SchemeBuilder.Build()
	if err != nil {
		panic(err.Error())
	}

	cli := fake2.NewClientBuilder().WithScheme(schema).WithStatusSubresource(registerSubresourceList()...).Build()

	// Initialize test reader/writers
	initRW(cli, cli, fakeClient, nil, nil, true)

	code := m.Run()
	os.Exit(code)
}

func registerSubresourceList() []client.Object {
	return []client.Object{
		&v1.Cluster{},
		&v1.EndpointService{},
		&v1.IAM{},
		&v1.PrivateEndpoint{},
		&v1.S3{},
		&v1.IntegrationTask{},
		&vmv1.VMRule{},
		&prometheusv1.PrometheusRule{},
	}
}

func createSegmentConfigMap(ctx context.Context) error {
	newConfig := map[string]string{
		constants.DataAccountKeyStartID: minSegmentStart,
	}

	_, err := fakeClient.CoreV1().
		ConfigMaps(constants.ObservabilityNamespace).
		Create(ctx, &corev1.ConfigMap{
			ObjectMeta: metav1.ObjectMeta{
				Name: constants.DataAccountSegmentConfigMap,
			},
			Data: newConfig,
		}, metav1.CreateOptions{})

	return err
}
