"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Lockfile = exports.PoetrySchemaToml = exports.PoetrySchema = exports.PoetrySectionSchema = exports.PoetryGroupRecord = exports.PoetryDependencyRecord = void 0;
const tslib_1 = require("tslib");
const zod_1 = require("zod");
const url_1 = require("../../../util/git/url");
const regex_1 = require("../../../util/regex");
const schema_utils_1 = require("../../../util/schema-utils");
const git_refs_1 = require("../../datasource/git-refs");
const github_tags_1 = require("../../datasource/github-tags");
const pypi_1 = require("../../datasource/pypi");
const pep440Versioning = tslib_1.__importStar(require("../../versioning/pep440"));
const poetryVersioning = tslib_1.__importStar(require("../../versioning/poetry"));
const PoetryPathDependency = zod_1.z
    .object({
    path: zod_1.z.string(),
    version: zod_1.z.string().optional().catch(undefined),
})
    .transform(({ version }) => {
    const dep = {
        datasource: pypi_1.PypiDatasource.id,
        skipReason: 'path-dependency',
    };
    if (version) {
        dep.currentValue = version;
    }
    return dep;
});
const PoetryGitDependency = zod_1.z
    .object({
    git: zod_1.z.string(),
    tag: zod_1.z.string().optional().catch(undefined),
    version: zod_1.z.string().optional().catch(undefined),
})
    .transform(({ git, tag, version }) => {
    if (!tag) {
        const res = {
            datasource: git_refs_1.GitRefsDatasource.id,
            packageName: git,
            skipReason: 'git-dependency',
        };
        if (version) {
            res.currentValue = version;
        }
        return res;
    }
    const parsedUrl = (0, url_1.parseGitUrl)(git);
    if (parsedUrl.source !== 'github.com') {
        return {
            datasource: git_refs_1.GitRefsDatasource.id,
            currentValue: tag,
            packageName: git,
            skipReason: 'git-dependency',
        };
    }
    const { owner, name } = parsedUrl;
    const repo = `${owner}/${name}`;
    return {
        datasource: github_tags_1.GithubTagsDatasource.id,
        currentValue: tag,
        packageName: repo,
    };
});
const PoetryPypiDependency = zod_1.z.union([
    zod_1.z
        .object({ version: zod_1.z.string().optional() })
        .transform(({ version: currentValue }) => {
        if (!currentValue) {
            return { datasource: pypi_1.PypiDatasource.id };
        }
        return {
            datasource: pypi_1.PypiDatasource.id,
            managerData: { nestedVersion: true },
            currentValue,
        };
    }),
    zod_1.z.string().transform((version) => ({
        datasource: pypi_1.PypiDatasource.id,
        currentValue: version,
        managerData: { nestedVersion: false },
    })),
]);
const PoetryDependencySchema = zod_1.z.union([
    PoetryPathDependency,
    PoetryGitDependency,
    PoetryPypiDependency,
]);
const PoetryArraySchema = zod_1.z.array(zod_1.z.unknown()).transform(() => ({
    datasource: pypi_1.PypiDatasource.id,
    skipReason: 'multiple-constraint-dep',
}));
const PoetryValue = zod_1.z.union([PoetryDependencySchema, PoetryArraySchema]);
exports.PoetryDependencyRecord = (0, schema_utils_1.LooseRecord)(zod_1.z.string(), PoetryValue.transform((dep) => {
    if (dep.skipReason) {
        return dep;
    }
    // istanbul ignore if: normaly should not happen
    if (!dep.currentValue) {
        dep.skipReason = 'unspecified-version';
        return dep;
    }
    if (pep440Versioning.isValid(dep.currentValue)) {
        dep.versioning = pep440Versioning.id;
        return dep;
    }
    if (poetryVersioning.isValid(dep.currentValue)) {
        dep.versioning = poetryVersioning.id;
        return dep;
    }
    dep.skipReason = 'invalid-version';
    return dep;
})).transform((record) => {
    for (const [depName, dep] of Object.entries(record)) {
        dep.depName = depName;
        if (!dep.packageName) {
            const pep503NormalizeRegex = (0, regex_1.regEx)(/[-_.]+/g);
            const packageName = depName
                .toLowerCase()
                .replace(pep503NormalizeRegex, '-');
            if (depName !== packageName) {
                dep.packageName = packageName;
            }
        }
    }
    return record;
});
exports.PoetryGroupRecord = (0, schema_utils_1.LooseRecord)(zod_1.z.string(), zod_1.z.object({
    dependencies: exports.PoetryDependencyRecord.optional(),
}));
exports.PoetrySectionSchema = zod_1.z.object({
    dependencies: exports.PoetryDependencyRecord.optional(),
    'dev-dependencies': exports.PoetryDependencyRecord.optional(),
    extras: exports.PoetryDependencyRecord.optional(),
    group: exports.PoetryGroupRecord.optional(),
    source: zod_1.z
        .array(zod_1.z.object({ name: zod_1.z.string(), url: zod_1.z.string().optional() }))
        .optional(),
});
exports.PoetrySchema = zod_1.z.object({
    tool: zod_1.z
        .object({
        poetry: exports.PoetrySectionSchema.optional(),
    })
        .optional(),
    'build-system': zod_1.z
        .object({
        requires: zod_1.z.array(zod_1.z.string()),
        'build-backend': zod_1.z.string().optional(),
    })
        .optional(),
});
exports.PoetrySchemaToml = schema_utils_1.Toml.pipe(exports.PoetrySchema);
const poetryConstraint = {
    '1.0': '<1.1.0',
    '1.1': '<1.3.0',
    '2.0': '>=1.3.0',
};
exports.Lockfile = schema_utils_1.Toml.pipe(zod_1.z.object({
    package: (0, schema_utils_1.LooseArray)(zod_1.z
        .object({
        name: zod_1.z.string(),
        version: zod_1.z.string(),
    })
        .transform(({ name, version }) => [name, version]))
        .transform((entries) => Object.fromEntries(entries))
        .catch({}),
    metadata: zod_1.z
        .object({
        'lock-version': zod_1.z
            .string()
            .transform((lockVersion) => poetryConstraint[lockVersion])
            .optional()
            .catch(undefined),
        'python-versions': zod_1.z.string().optional().catch(undefined),
    })
        .transform(({ 'lock-version': poetryConstraint, 'python-versions': pythonVersions, }) => ({
        poetryConstraint,
        pythonVersions,
    }))
        .catch({
        poetryConstraint: undefined,
        pythonVersions: undefined,
    }),
})).transform(({ package: lock, metadata: { poetryConstraint, pythonVersions } }) => ({
    lock,
    poetryConstraint,
    pythonVersions,
}));
//# sourceMappingURL=schema.js.map