import { createNeedleCallback } from '../../base/support/index.js';
const tomlItemToString = (item) => `{ ${Object.entries(item)
    .filter(([_key, value]) => value !== undefined)
    .map(([key, value]) => `${key} = "${value}"`)
    .join(', ')} }`;
const gradleNameToReference = (name) => name.replaceAll('-', '.');
const scopeSortOrder = {
    'implementation platform': 1,
    implementation: 2,
    compileOnly: 3,
    runtimeOnly: 4,
    testImplementation: 5,
    testRuntimeOnly: 6,
};
const wrapScope = (scope, dependency, closure) => {
    if (closure?.length || scope === 'implementation platform') {
        return `${scope}(${dependency})${closure?.length ? ` {\n${closure.join('\n')}\n}` : ''}`;
    }
    return `${scope} ${dependency}`;
};
const serializeDependency = (dependency) => {
    if ('libraryName' in dependency) {
        return wrapScope(dependency.scope, `libs.${gradleNameToReference(dependency.libraryName)}`, dependency.closure);
    }
    const { groupId, artifactId, version, classifier, scope, closure } = dependency;
    return wrapScope(scope, classifier && !version
        ? `group: "${groupId}", name: "${artifactId}", classifier: "${classifier}"`
        : `"${groupId}:${artifactId}${version ? `:${version}` : ''}${classifier ? `:${classifier}` : ''}"`, closure);
};
export const gradleNeedleOptionsWithDefaults = (options) => {
    const { gradleFile = 'build.gradle', gradleVersionCatalogFile = 'gradle/libs.versions.toml' } = options;
    return { gradleFile, gradleVersionCatalogFile };
};
export const sortDependencies = (a, b) => {
    let ret = (scopeSortOrder[a.scope] ?? 100) - (scopeSortOrder[b.scope] ?? 100);
    if (ret !== 0 || a.scope === 'implementation platform') {
        return ret;
    }
    ret = a.scope.localeCompare(b.scope);
    if (ret !== 0) {
        return ret;
    }
    if ('libraryName' in a || 'libraryName' in b) {
        if ('libraryName' in a && 'libraryName' in b) {
            return a.libraryName.localeCompare(b.libraryName);
        }
        return 'libraryName' in a ? -1 : 1;
    }
    ret = a.groupId.localeCompare(b.groupId);
    if (ret !== 0) {
        const aIsSpring = a.groupId.startsWith('org.springframework.');
        const bIsSpring = b.groupId.startsWith('org.springframework.');
        if (aIsSpring !== bIsSpring && (aIsSpring || bIsSpring)) {
            return aIsSpring ? -1 : 1;
        }
        return ret;
    }
    return ret === 0 ? a.artifactId.localeCompare(b.artifactId) : ret;
};
export const applyFromGradleCallback = ({ script }) => createNeedleCallback({
    needle: 'gradle-apply-from',
    contentToAdd: `apply from: "${script}"`,
});
export const addGradleDependenciesCallback = (dependencies) => createNeedleCallback({
    needle: 'gradle-dependency',
    contentToAdd: dependencies.map(serializeDependency),
});
export const addGradleDependenciesCatalogVersionCallback = (versions) => createNeedleCallback({
    needle: 'gradle-dependency-catalog-version',
    contentToAdd: versions.map(({ name, version }) => `${name} = "${version}"`),
});
export const addGradleDependencyCatalogLibrariesCallback = (libraries) => createNeedleCallback({
    needle: 'gradle-dependency-catalog-libraries',
    contentToAdd: libraries.map(({ libraryName, scope: _scope, closure: _closure, ...others }) => 'library' in others ? `${libraryName} = "${others.library}"` : `${libraryName} = ${tomlItemToString(others)}`),
});
export const addGradleDependencyCatalogPluginsCallback = (plugins) => createNeedleCallback({
    needle: 'gradle-dependency-catalog-plugins',
    contentToAdd: plugins.map(({ pluginName, addToBuild: _addToBuild, ...others }) => 'plugin' in others ? `${pluginName} = "${others.plugin}"` : `${pluginName} = ${tomlItemToString(others)}`),
});
export const addGradlePluginFromCatalogCallback = (plugins) => createNeedleCallback({
    needle: 'gradle-plugins',
    contentToAdd: plugins
        .filter(({ addToBuild }) => addToBuild)
        .map(({ pluginName }) => `alias(libs.plugins.${gradleNameToReference(pluginName)})`),
});
export const addGradlePluginCallback = ({ id, version }) => createNeedleCallback({
    needle: 'gradle-plugins',
    contentToAdd: `id "${id}"${version ? ` version "${version}"` : ''}`,
});
export const addGradlePluginManagementCallback = ({ id, version }) => createNeedleCallback({
    needle: 'gradle-plugin-management-plugins',
    contentToAdd: `id "${id}" version "${version}"`,
});
export const addGradlePropertyCallback = ({ comment, property, value }) => createNeedleCallback({
    needle: 'gradle-property',
    contentToAdd: `${typeof comment === 'string' ? `## ${comment}\n` : ''}${property}${typeof value === 'string' ? `=${value}` : ''}`,
    contentToCheck: new RegExp(`\n${property}${typeof value === 'string' ? '=' : '\n'}`),
    autoIndent: false,
});
export const addGradleMavenRepositoryCallback = ({ url, username, password }) => createNeedleCallback({
    needle: 'gradle-repositories',
    contentToAdd: `
maven {
    url "${url}"${username || password ? `
    credentials {${username ? `
        username = "${username}"` : ''}${password ? `
        password = "${password}"` : ''}
    }` : ''}
}`,
});
