import { LogLevel, StageId } from '@core/types'
import { ClassConstructor, plainToInstance } from 'class-transformer'
import { IsEnum, validateSync } from 'class-validator'
import 'reflect-metadata'

export class EnvironmentVariables {
	@IsEnum(StageId)
	APP_MODE: StageId

	@IsEnum(LogLevel)
	LOG_LEVEL: LogLevel = LogLevel.INFO
}

export function validate(config: Record<string, unknown>): typeof EnvironmentVariables {
	return validateType(config, EnvironmentVariables)
}

export function validateType<T extends ClassConstructor<U>, U extends EnvironmentVariables>(
	config: Record<string, unknown>,
	type: T,
): T {
	const validatedConfig = plainToInstance(type, config, {
		enableImplicitConversion: true,
	})

	const errors = validateSync(validatedConfig, {
		skipMissingProperties: false,
	})

	if (errors.length > 0) {
		throw new Error(errors.toString())
	}

	return validatedConfig as unknown as T
}

export function type<T>(type: T): type is T {
	return true
}
