import { getMatches } from "../file-matching.js";
import { defineSource } from "../source.js";
import { nonEmptyString, optionalUrl, stringArray } from "../utilities/schema-primitives.js";
import { readFile } from "node:fs/promises";
import { resolve } from "node:path";
import is from "@sindresorhus/is";
import { z } from "zod";
import { parse } from "yaml";
//#region src/lib/sources/go-goreleaser-yaml.ts
const goreleaserDataSchema = z.object({
	description: nonEmptyString,
	homepage: optionalUrl,
	license: nonEmptyString,
	maintainer: nonEmptyString,
	operating_systems: stringArray,
	project_name: nonEmptyString,
	repository_url: optionalUrl,
	vendor: nonEmptyString
});
/** Map Go OS identifiers to human-readable names. */
const GOOS_MAP = {
	aix: "AIX",
	android: "Android",
	darwin: "macOS",
	dragonfly: "DragonFly BSD",
	freebsd: "FreeBSD",
	illumos: "illumos",
	ios: "iOS",
	js: "JavaScript",
	linux: "Linux",
	netbsd: "NetBSD",
	openbsd: "OpenBSD",
	plan9: "Plan 9",
	solaris: "Solaris",
	wasip1: "WASI",
	windows: "Windows"
};
function isPlainObject(value) {
	return typeof value === "object" && value !== null && !Array.isArray(value);
}
function isNonEmptyString(value) {
	return typeof value === "string" && value.trim().length > 0;
}
/**
* Get the first non-empty string value of a given field from an array of
* package-manager section entries. Skips Go template strings (containing `{{`).
*/
function firstString(sections, field) {
	for (const section of sections) if (isPlainObject(section)) {
		const value = section[field];
		if (isNonEmptyString(value) && !value.includes("{{")) return value.trim();
	}
}
/**
* Collect all section entries for a given key, handling both v1 singular
* and v2 plural forms.
*/
function collectSections(data, ...keys) {
	const result = [];
	for (const key of keys) {
		const value = data[key];
		if (is.array(value)) result.push(...value);
		else if (isPlainObject(value)) result.push(value);
	}
	return result;
}
/**
* Parse a .goreleaser.yml/.yaml file and return structured metadata.
*
* Aggregates metadata from multiple package-manager sections (nfpms, brews,
* scoops, snapcrafts, chocolateys, winget, aurs) with defined priority.
* Extracts operating systems from builds[].goos.
*/
function parse$1(source) {
	let data;
	try {
		data = parse(source);
	} catch {
		return;
	}
	if (!isPlainObject(data)) return void 0;
	const result = {
		description: void 0,
		homepage: void 0,
		license: void 0,
		maintainer: void 0,
		operating_systems: [],
		project_name: void 0,
		repository_url: void 0,
		vendor: void 0
	};
	if (isNonEmptyString(data.project_name)) result.project_name = data.project_name;
	const nfpms = collectSections(data, "nfpms", "nfpm");
	const brews = collectSections(data, "brews", "brew", "homebrew_casks");
	const snaps = collectSections(data, "snapcrafts", "snapcraft");
	const scoops = collectSections(data, "scoops", "scoop");
	const chocs = collectSections(data, "chocolateys", "chocolatey");
	const winget = collectSections(data, "winget");
	const aurs = collectSections(data, "aurs", "aur");
	const krews = collectSections(data, "krews", "krew");
	const allSections = [
		...nfpms,
		...brews,
		...snaps,
		...scoops,
		...chocs,
		...winget,
		...aurs,
		...krews
	];
	result.description = firstString(allSections, "description") ?? firstString(snaps, "summary") ?? firstString(chocs, "summary") ?? firstString(winget, "short_description");
	result.homepage = firstString(allSections, "homepage") ?? firstString(chocs, "project_url");
	result.license = firstString(allSections, "license");
	result.maintainer = firstString(nfpms, "maintainer") ?? firstString(aurs, "maintainer");
	result.vendor = firstString(nfpms, "vendor") ?? firstString(chocs, "owners") ?? firstString(winget, "publisher");
	if (isPlainObject(data.release)) {
		const { release } = data;
		if (isPlainObject(release.github)) {
			const gh = release.github;
			if (typeof gh.owner === "string" && typeof gh.name === "string") result.repository_url = `https://github.com/${gh.owner}/${gh.name}`;
		} else if (isPlainObject(release.gitlab)) {
			const gl = release.gitlab;
			if (typeof gl.owner === "string" && typeof gl.name === "string") result.repository_url = `https://gitlab.com/${gl.owner}/${gl.name}`;
		}
	}
	const goosSet = /* @__PURE__ */ new Set();
	const builds = collectSections(data, "builds", "build");
	for (const build of builds) if (isPlainObject(build)) {
		const { goos } = build;
		if (Array.isArray(goos)) {
			for (const os of goos) if (typeof os === "string") goosSet.add(os.toLowerCase());
		}
	}
	result.operating_systems = [...goosSet].map((os) => GOOS_MAP[os] ?? os.charAt(0).toUpperCase() + os.slice(1));
	return goreleaserDataSchema.parse(result);
}
const goGoreleaserYamlSource = defineSource({
	async discover(context) {
		return getMatches(context.options, [".goreleaser.yml", ".goreleaser.yaml"]);
	},
	key: "goGoreleaserYaml",
	async parse(input, context) {
		const data = parse$1(await readFile(resolve(context.options.path, input), "utf8"));
		if (data !== void 0) return {
			data,
			source: input
		};
	},
	phase: 1
});
//#endregion
export { goGoreleaserYamlSource };
