import { getMatches } from "../file-matching.js";
import { defineSource } from "../source.js";
import { nonEmptyString, optionalUrl, stringArray } from "../utilities/schema-primitives.js";
import { splitCommaSeparated } from "../utilities/template-helpers.js";
import { parseConfigparser, splitMultiline } from "../parsers/configparser-parser.js";
import { readFile } from "node:fs/promises";
import { resolve } from "node:path";
import { z } from "zod";
//#region src/lib/sources/python-setup-cfg.ts
const setupCfgDataSchema = z.object({
	author: nonEmptyString,
	author_email: nonEmptyString,
	classifiers: stringArray,
	description: nonEmptyString,
	download_url: optionalUrl,
	extras_require: z.record(z.string(), z.array(z.string())),
	install_requires: stringArray,
	keywords: z.array(z.string()).optional(),
	license: nonEmptyString,
	long_description: nonEmptyString,
	maintainer: nonEmptyString,
	maintainer_email: nonEmptyString,
	name: nonEmptyString,
	project_urls: z.record(z.string(), z.string()),
	python_requires: nonEmptyString,
	url: optionalUrl,
	version: nonEmptyString
});
/** Simple string attributes to extract from [metadata]. */
const STRING_ATTRS = new Set([
	"author",
	"author_email",
	"description",
	"download_url",
	"license",
	"long_description",
	"maintainer",
	"maintainer_email",
	"name",
	"url",
	"version"
]);
/**
* Parse a setup.cfg file and return structured metadata.
*
* Extracts fields from the `[metadata]` and `[options]` sections,
* including multi-line values like classifiers and install_requires.
*/
function parse(source) {
	const sections = parseConfigparser(source);
	const metadata = sections.metadata ?? {};
	const options = sections.options ?? {};
	const data = {
		author: void 0,
		author_email: void 0,
		classifiers: [],
		description: void 0,
		download_url: void 0,
		extras_require: {},
		install_requires: [],
		keywords: void 0,
		license: void 0,
		long_description: void 0,
		maintainer: void 0,
		maintainer_email: void 0,
		name: void 0,
		project_urls: {},
		python_requires: void 0,
		url: void 0,
		version: void 0
	};
	for (const key of STRING_ATTRS) {
		const value = metadata[key];
		if (value) Object.assign(data, { [key]: value });
	}
	if (metadata.classifiers) data.classifiers = splitMultiline(metadata.classifiers);
	if (metadata.keywords) data.keywords = splitCommaSeparated(metadata.keywords);
	if (metadata.project_urls) for (const line of splitMultiline(metadata.project_urls)) {
		const eqIndex = line.indexOf("=");
		if (eqIndex > 0) {
			const label = line.slice(0, eqIndex).trim();
			const url = line.slice(eqIndex + 1).trim();
			if (url) data.project_urls[label] = url;
		}
	}
	if (options.install_requires) data.install_requires = splitMultiline(options.install_requires);
	if (options.python_requires) data.python_requires = options.python_requires;
	const extrasSection = sections["options.extras_require"];
	if (extrasSection) for (const [key, value] of Object.entries(extrasSection)) data.extras_require[key] = splitMultiline(value);
	return setupCfgDataSchema.parse(data);
}
const pythonSetupCfgSource = defineSource({
	async discover(context) {
		return getMatches(context.options, ["setup.cfg"]);
	},
	key: "pythonSetupCfg",
	async parse(input, context) {
		return {
			data: parse(await readFile(resolve(context.options.path, input), "utf8")),
			source: input
		};
	},
	phase: 1
});
//#endregion
export { pythonSetupCfgSource };
