"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.loadLightdashProjectConfig = void 0;
const tslib_1 = require("tslib");
const ajv_1 = tslib_1.__importDefault(require("ajv"));
const ajv_errors_1 = tslib_1.__importDefault(require("ajv-errors"));
const better_ajv_errors_1 = tslib_1.__importDefault(require("better-ajv-errors"));
const yaml = tslib_1.__importStar(require("js-yaml"));
const parameters_1 = require("../compiler/parameters");
const lightdash_project_config_1_0_json_1 = tslib_1.__importDefault(require("../schemas/json/lightdash-project-config-1.0.json"));
const errors_1 = require("../types/errors");
const lightdashProjectConfig_1 = require("../types/lightdashProjectConfig");
const timeFrames_1 = require("../types/timeFrames");
const defaultConfig = {
    spotlight: lightdashProjectConfig_1.DEFAULT_SPOTLIGHT_CONFIG,
};
const loadLightdashProjectConfig = async (yamlFileContents, onLoaded) => {
    if (yamlFileContents.trim() === '') {
        return defaultConfig;
    }
    // Type assertion for the loaded YAML config
    const loadedConfig = yaml.load(yamlFileContents);
    // Merge the loaded config with the default config
    const configFile = {
        ...defaultConfig,
        ...loadedConfig,
    };
    const ajv = new ajv_1.default({
        coerceTypes: true,
        allErrors: true,
        allowUnionTypes: true,
    });
    // This method call extends JSON schema to utilize AJV Errors
    (0, ajv_errors_1.default)(ajv);
    const validate = ajv.compile(lightdash_project_config_1_0_json_1.default);
    if (!validate(configFile)) {
        const errors = (0, better_ajv_errors_1.default)(lightdash_project_config_1_0_json_1.default, configFile, validate.errors || [], { indent: 2 });
        throw new errors_1.ParseError(`Invalid lightdash.config.yml with errors:\n${errors}`);
    }
    if (configFile.parameters == null) {
        configFile.parameters = undefined;
    }
    const { isInvalid: hasInvalidParameterNames, invalidParameters, reservedParameters, } = (0, parameters_1.validateParameterNames)(configFile.parameters);
    if (hasInvalidParameterNames) {
        throw new errors_1.LightdashProjectConfigError(`Invalid lightdash.config.yml with invalid parameter names: ${invalidParameters.join(', ')}`, { invalidParameters });
    }
    // Collisions with a reserved name don't fail config load: the user param wins; warn.
    if (reservedParameters.length > 0) {
        console.warn(`lightdash.config.yml: parameter${reservedParameters.length > 1 ? 's' : ''} ${reservedParameters.join(', ')} ${reservedParameters.length > 1 ? 'override' : 'overrides'} a reserved system variable and will take priority over it.`);
    }
    if (configFile.custom_granularities) {
        const timeFrameValues = new Set(Object.values(timeFrames_1.TimeFrames).map((v) => v.toLowerCase()));
        const conflicting = Object.keys(configFile.custom_granularities).filter((name) => timeFrameValues.has(name.toLowerCase()));
        if (conflicting.length > 0) {
            throw new errors_1.LightdashProjectConfigError(`Custom granularity names conflict with standard time intervals: ${conflicting.join(', ')}`, { invalidParameters: conflicting });
        }
    }
    if (onLoaded) {
        await onLoaded(configFile);
    }
    return configFile;
};
exports.loadLightdashProjectConfig = loadLightdashProjectConfig;
//# sourceMappingURL=loadLightdashProjectConfig.js.map