import "../../../constants/error-messages.js";
import { GlobalConfig } from "../../../config/global.js";
import { logger } from "../../../logger/index.js";
import { find } from "../../../util/host-rules.js";
import { readLocalFile } from "../../../util/fs/index.js";
import { exec } from "../../../util/exec/index.js";
import { findGithubToken } from "../../../util/check-token.js";
import { getConfigType, getLockFileName } from "./lockfile.js";
import { isNonEmptyStringAndNotWhitespace, isString } from "@sindresorhus/is";
import { quote } from "shlex";
import upath from "upath";
//#region lib/modules/manager/mise/artifacts.ts
/**
* Resolver tools that mise may invoke while running `mise lock`, for instance to convert an inexact version like `1` against the npm registry.
*
* NOTE: this will install all relevant tools, regardless of what the given mise configuration uses.
*
* @see https://mise.jdx.dev/dev-tools/backends/npm.html
* @see https://mise.jdx.dev/dev-tools/backends/go.html
* @see https://mise.jdx.dev/dev-tools/backends/gem.html
*/
function getMiseLockToolConstraints(constraints) {
	return [
		{
			toolName: "mise",
			constraint: constraints?.mise
		},
		{
			toolName: "node",
			constraint: constraints?.node
		},
		{
			toolName: "npm",
			constraint: constraints?.npm
		},
		{
			toolName: "golang",
			constraint: constraints?.go
		},
		{
			toolName: "ruby",
			constraint: constraints?.ruby
		}
	];
}
/**
* Updates mise lock files when dependencies are updated.
* Runs `mise lock` for lock file maintenance or `mise lock <tools>` for targeted updates.
*/
async function updateArtifacts({ packageFileName, updatedDeps, config }) {
	const lockFileName = getLockFileName(packageFileName);
	const existingLockFileContent = await readLocalFile(lockFileName, "utf8");
	if (!existingLockFileContent) {
		logger.debug({ lockFileName }, "No mise lock file found");
		return null;
	}
	if (!GlobalConfig.get("allowedUnsafeExecutions").includes("mise")) {
		logger.once.warn("`mise lock` was requested to run, but `mise` is not permitted in the allowedUnsafeExecutions");
		return null;
	}
	const { isLocal, env } = getConfigType(packageFileName);
	const localFlag = isLocal ? " --local" : "";
	let lockCmd;
	if (config.isLockFileMaintenance) lockCmd = `mise lock${localFlag}`;
	else {
		const tools = updatedDeps.map(({ depName }) => depName).filter(isNonEmptyStringAndNotWhitespace).map(quote).join(" ");
		lockCmd = tools ? `mise lock${localFlag} ${tools}` : `mise lock${localFlag}`;
	}
	const extraEnv = {};
	if (env) extraEnv.MISE_ENV = env;
	const token = findGithubToken(find({
		hostType: "github",
		url: "https://api.github.com/"
	}));
	if (token) extraEnv.GITHUB_TOKEN = token;
	const execOptions = {
		cwdFile: packageFileName,
		extraEnv,
		toolConstraints: getMiseLockToolConstraints(config.constraints),
		docker: {}
	};
	const trustCmd = `mise trust ${quote(upath.basename(packageFileName))}`;
	try {
		await exec([trustCmd, lockCmd], execOptions);
		const newLockFileContent = await readLocalFile(lockFileName, "utf8");
		if (!newLockFileContent || existingLockFileContent === newLockFileContent) return null;
		logger.debug({ lockFileName }, "Returning updated mise lock file");
		return [{ file: {
			type: "addition",
			path: lockFileName,
			contents: newLockFileContent
		} }];
	} catch (err) {
		// istanbul ignore if: not worth testing
		if (err.message === "temporary-error") throw err;
		const errorOutput = [
			err.stdout,
			err.stderr,
			err.message
		].filter(isString).join("\n");
		logger.warn({ err }, `Error updating ${lockFileName}`);
		return [{ artifactError: {
			fileName: lockFileName,
			stderr: errorOutput
		} }];
	}
}
//#endregion
export { updateArtifacts };

//# sourceMappingURL=artifacts.js.map