package main

import (
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/tidbcloud/cluster-service-ng/config"
)

type jobsToRegister struct {
	MeteringDiskInfo     bool
	ManualBackupMetering bool
	WorkerNodeMetering   bool
}

func determineJobsToRegister(cfg *config.Config) jobsToRegister {
	jobs := jobsToRegister{}

	if cfg.ServerConfig.ControlPlaneMetering.MetadataEnabled() {
		jobs.ManualBackupMetering = cfg.ServerConfig.ControlPlaneMetering.Enable
		jobs.MeteringDiskInfo = cfg.ServerConfig.ControlPlaneMetering.Enable
	}

	if cfg.ServerConfig.ControlPlaneMetering.WorkerNodeEnabled() {
		jobs.WorkerNodeMetering = true
	}

	return jobs
}

func TestStartupCompatibility_WorkerNodeDisabled_ControlPlaneEnabled(t *testing.T) {
	cfg := &config.Config{
		ServerConfig: &config.ServerConfig{
			ControlPlaneMetering: &config.MeteringConfig{
				Enable: true,
				WorkerNode: &config.WorkerNodeMeteringConfig{
					Enable: false,
				},
			},
		},
	}

	jobsToRegister := determineJobsToRegister(cfg)

	assert.True(t, jobsToRegister.MeteringDiskInfo, "disk metering job should be registered when controlPlaneMetering is enabled")
	assert.True(t, jobsToRegister.ManualBackupMetering, "manual backup metering job should be registered when controlPlaneMetering is enabled")
	assert.False(t, jobsToRegister.WorkerNodeMetering, "worker-node metering job should NOT be registered when controlPlaneMetering.workerNode is disabled")
}

func TestStartupCompatibility_WorkerNodeDisabled_ControlPlaneDisabled(t *testing.T) {
	cfg := &config.Config{
		ServerConfig: &config.ServerConfig{
			ControlPlaneMetering: &config.MeteringConfig{
				Enable: false,
				WorkerNode: &config.WorkerNodeMeteringConfig{
					Enable: false,
				},
			},
		},
	}

	jobsToRegister := determineJobsToRegister(cfg)

	assert.False(t, jobsToRegister.MeteringDiskInfo, "disk metering job should NOT be registered")
	assert.False(t, jobsToRegister.ManualBackupMetering, "manual backup metering job should NOT be registered")
	assert.False(t, jobsToRegister.WorkerNodeMetering, "worker-node metering job should NOT be registered")
}

func TestStartupCompatibility_WorkerNodeEnabled_ControlPlaneEnabled(t *testing.T) {
	cfg := &config.Config{
		ServerConfig: &config.ServerConfig{
			ControlPlaneMetering: &config.MeteringConfig{
				Enable: true,
				WorkerNode: &config.WorkerNodeMeteringConfig{
					Enable: true,
				},
			},
		},
	}

	jobsToRegister := determineJobsToRegister(cfg)

	assert.True(t, jobsToRegister.MeteringDiskInfo, "disk metering job should be registered")
	assert.True(t, jobsToRegister.ManualBackupMetering, "manual backup metering job should be registered")
	assert.True(t, jobsToRegister.WorkerNodeMetering, "worker-node metering job should be registered")
}

func TestStartupCompatibility_WorkerNodeEnabled_ControlPlaneDisabled(t *testing.T) {
	cfg := &config.Config{
		ServerConfig: &config.ServerConfig{
			ControlPlaneMetering: &config.MeteringConfig{
				Enable: false,
				WorkerNode: &config.WorkerNodeMeteringConfig{
					Enable: true,
				},
			},
		},
	}

	jobsToRegister := determineJobsToRegister(cfg)

	assert.False(t, jobsToRegister.MeteringDiskInfo, "disk metering job should NOT be registered when controlPlaneMetering is disabled")
	assert.False(t, jobsToRegister.ManualBackupMetering, "manual backup metering job should NOT be registered when controlPlaneMetering is disabled")
	assert.True(t, jobsToRegister.WorkerNodeMetering, "worker-node metering job should be registered when controlPlaneMetering.workerNode is enabled")
}
