import { EMULSIFY_PROJECT_CONFIG_FILE, EMULSIFY_SYSTEM_CONFIG_FILE, } from '../../lib/constants.js';
import CliError from '../../lib/CliError.js';
import cloneIntoCache from '../../util/cache/cloneIntoCache.js';
import getJsonFromCachedFile from '../../util/cache/getJsonFromCachedFile.js';
import getGitRepoNameFromUrl from '../../util/getGitRepoNameFromUrl.js';
import getEmulsifyConfig from '../../util/project/getEmulsifyConfig.js';
export class EmulsifySystemError extends CliError {
    constructor(message) {
        super(message);
        this.name = 'EmulsifySystemError';
    }
}
export async function withEmulsifySystem(actionLabel) {
    const emulsifyConfig = await getEmulsifyConfig();
    if (!emulsifyConfig) {
        throw new EmulsifySystemError('No Emulsify project detected. You must run this command within an existing Emulsify project. For more information about creating Emulsify projects, run "emulsify init --help"');
    }
    const systemReference = emulsifyConfig.system;
    const variantReference = emulsifyConfig.variant;
    if (!systemReference || !variantReference) {
        throw new EmulsifySystemError(`You must select and install a system before you can ${actionLabel}. To see a list of out-of-the-box systems, run "emulsify system list". You can install a system by running "emulsify system install [name]"`);
    }
    const systemName = getGitRepoNameFromUrl(systemReference.repository);
    if (!systemName) {
        throw new EmulsifySystemError(`The system specified in your project configuration is not valid. Please make sure your ${EMULSIFY_PROJECT_CONFIG_FILE} file contains a system.repository value that is a valid git url`);
    }
    try {
        await cloneIntoCache('systems', [systemName])(systemReference);
    }
    catch {
        throw new EmulsifySystemError('The system specified in your project configuration is not clone-able, or has an invalid checkout value.');
    }
    const systemConf = await getJsonFromCachedFile('systems', [systemName], systemReference.checkout, EMULSIFY_SYSTEM_CONFIG_FILE);
    if (!systemConf) {
        throw new EmulsifySystemError(`Unable to load configuration for the ${systemName} system. Please make sure the system is installed.`);
    }
    const variantName = variantReference.platform;
    const variantConf = systemConf.variants?.find(({ platform }) => platform === variantName);
    if (!variantConf) {
        throw new EmulsifySystemError(`Unable to find configuration for the variant ${variantName} within the system ${systemName}.`);
    }
    return {
        emulsifyConfig: {
            ...emulsifyConfig,
            system: systemReference,
            variant: variantReference,
        },
        systemName,
        systemConf,
        variantConf,
    };
}
