import { TEMPORARY_ERROR } from "../../../constants/error-messages.js";
import { logger } from "../../../logger/index.js";
import { deleteLocalFile, getSiblingFileName, localPathExists, readLocalFile } from "../../../util/fs/index.js";
import { DockerDatasource } from "../../datasource/docker/index.js";
import { HelmDatasource } from "../../datasource/helm/index.js";
import { exec } from "../../../util/exec/index.js";
import { getRepoStatus } from "../../../util/git/index.js";
import { parseKustomize } from "./extract.js";
import { generateHelmEnvs } from "./common.js";
import { isNonEmptyString, isNullOrUndefined } from "@sindresorhus/is";
import upath from "upath";
import { quote } from "shlex";

//#region lib/modules/manager/kustomize/artifacts.ts
async function localExistingChartPath(chartHome, dependencyName, version) {
	const folderName = `${dependencyName}-${version}`;
	const path = upath.join(chartHome, folderName);
	return await localPathExists(path) ? path : null;
}
function helmRepositoryArgs(repository, depName, datasource) {
	switch (datasource) {
		case HelmDatasource.id: return `--repo ${quote(repository)} ${quote(depName)}`;
		case DockerDatasource.id: return quote(`oci://${repository}`);
		default: throw new Error(`Unknown datasource: ${datasource}`);
	}
}
async function inflateHelmChart(flagEnabled, execOptions, chartHome, depName, repository, currentVersion, newVersion, datasource) {
	const currentChartExistingPath = await localExistingChartPath(chartHome, depName, currentVersion);
	if (!flagEnabled && isNullOrUndefined(currentChartExistingPath)) {
		logger.debug(`Not inflating Helm chart for ${depName} as kustomizeInflateHelmCharts is not enabled and the current version isn't inflated`);
		return;
	}
	if (isNonEmptyString(currentChartExistingPath) && isNonEmptyString(newVersion)) {
		logger.debug(`Deleting previous helm chart: ${currentChartExistingPath}`);
		await deleteLocalFile(currentChartExistingPath);
	}
	const versionToPull = newVersion ?? currentVersion;
	const versionToPullExistingPath = await localExistingChartPath(chartHome, depName, versionToPull);
	if (isNonEmptyString(versionToPullExistingPath)) {
		logger.debug(`Helm chart ${depName} version ${versionToPull} already exists at ${versionToPullExistingPath}`);
		return;
	}
	const folderName = `${depName}-${versionToPull}`;
	const untarDir = upath.join(chartHome, folderName);
	logger.debug(`Pulling helm chart ${depName} version ${versionToPull} to ${untarDir}`);
	await exec(`helm pull --untar --untardir ${quote(untarDir)} --version ${quote(versionToPull)} ${helmRepositoryArgs(repository, depName, datasource)}`, execOptions);
}
async function updateArtifacts({ packageFileName, updatedDeps, newPackageFileContent, config }) {
	logger.debug(`kustomize.updateArtifacts(${packageFileName})`);
	const project = parseKustomize(newPackageFileContent);
	const isUpdateOptionInflateChartArchives = config.postUpdateOptions?.includes("kustomizeInflateHelmCharts") === true;
	if (isNullOrUndefined(project)) return [{ artifactError: { stderr: "Failed to parse new package file content" } }];
	const chartHome = getSiblingFileName(packageFileName, project.helmGlobals?.chartHome ?? "charts");
	try {
		const helmToolConstraint = {
			toolName: "helm",
			constraint: config.constraints?.helm
		};
		const execOptions = {
			docker: {},
			extraEnv: generateHelmEnvs(config),
			toolConstraints: [helmToolConstraint]
		};
		for (const dependency of updatedDeps) {
			if (!dependency.currentVersion) continue;
			if (dependency.newVersion === dependency.currentVersion) continue;
			if (!isNonEmptyString(dependency.depName)) continue;
			if (dependency.depType !== "HelmChart") continue;
			let repository = null;
			switch (dependency.datasource) {
				case HelmDatasource.id:
					repository = dependency.registryUrls?.[0];
					break;
				case DockerDatasource.id:
					repository = dependency.packageName;
					break;
			}
			if (isNullOrUndefined(repository)) continue;
			await inflateHelmChart(isUpdateOptionInflateChartArchives, execOptions, chartHome, dependency.depName, repository, dependency.currentVersion, dependency.newVersion, dependency.datasource);
		}
		const status = await getRepoStatus();
		const chartsAddition = status?.not_added ?? [];
		const chartsDeletion = status?.deleted ?? [];
		const fileChanges = [];
		for (const file of chartsAddition) {
			if (!file.startsWith(chartHome)) continue;
			fileChanges.push({ file: {
				type: "addition",
				path: file,
				contents: await readLocalFile(file)
			} });
		}
		for (const file of chartsDeletion) {
			if (!file.startsWith(chartHome)) continue;
			fileChanges.push({ file: {
				type: "deletion",
				path: file
			} });
		}
		return fileChanges.length > 0 ? fileChanges : null;
	} catch (err) {
		if (err.message === TEMPORARY_ERROR) throw err;
		logger.debug({ err }, "Failed to inflate helm chart");
		return [{ artifactError: { stderr: err.message } }];
	}
}

//#endregion
export { updateArtifacts };
//# sourceMappingURL=artifacts.js.map