"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.extractPackageFile = void 0;
const tslib_1 = require("tslib");
const toml_1 = require("@iarna/toml");
const is_1 = tslib_1.__importDefault(require("@sindresorhus/is"));
const logger_1 = require("../../../logger");
const fs_1 = require("../../../util/fs");
const url_1 = require("../../../util/git/url");
const regex_1 = require("../../../util/regex");
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 locked_version_1 = require("./locked-version");
function extractFromDependenciesSection(parsedFile, section, poetryLockfile) {
    return extractFromSection(parsedFile.tool?.poetry?.[section], section, poetryLockfile);
}
function extractFromDependenciesGroupSection(parsedFile, group, poetryLockfile) {
    return extractFromSection(parsedFile.tool?.poetry?.group[group]?.dependencies, group, poetryLockfile);
}
function extractFromSection(sectionContent, depType, poetryLockfile) {
    if (!sectionContent) {
        return [];
    }
    const deps = [];
    for (const depName of Object.keys(sectionContent)) {
        if (depName === 'python' || depName === 'source') {
            continue;
        }
        const pep503NormalizeRegex = (0, regex_1.regEx)(/[-_.]+/g);
        let packageName = depName.toLowerCase().replace(pep503NormalizeRegex, '-');
        let skipReason = null;
        let currentValue = sectionContent[depName];
        let nestedVersion = false;
        let datasource = pypi_1.PypiDatasource.id;
        let lockedVersion = null;
        if (packageName in poetryLockfile) {
            lockedVersion = poetryLockfile[packageName];
        }
        if (!is_1.default.string(currentValue)) {
            const version = currentValue.version;
            const path = currentValue.path;
            const git = currentValue.git;
            if (version) {
                currentValue = version;
                nestedVersion = true;
                if (!!path || git) {
                    skipReason = path ? 'path-dependency' : 'git-dependency';
                }
            }
            else if (path) {
                currentValue = '';
                skipReason = 'path-dependency';
            }
            else if (git) {
                if (currentValue.tag) {
                    currentValue = currentValue.tag;
                    datasource = github_tags_1.GithubTagsDatasource.id;
                    const githubPackageName = extractGithubPackageName(git);
                    if (githubPackageName) {
                        packageName = githubPackageName;
                    }
                    else {
                        skipReason = 'git-dependency';
                    }
                }
                else {
                    currentValue = '';
                    skipReason = 'git-dependency';
                }
            }
            else {
                currentValue = '';
                skipReason = 'multiple-constraint-dep';
            }
        }
        const dep = {
            depName,
            depType,
            currentValue,
            managerData: { nestedVersion },
            datasource,
        };
        if (lockedVersion) {
            dep.lockedVersion = lockedVersion;
        }
        if (depName !== packageName) {
            dep.packageName = packageName;
        }
        if (skipReason) {
            dep.skipReason = skipReason;
        }
        else if (pep440Versioning.isValid(currentValue)) {
            dep.versioning = pep440Versioning.id;
        }
        else if (poetryVersioning.isValid(currentValue)) {
            dep.versioning = poetryVersioning.id;
        }
        else {
            dep.skipReason = 'unspecified-version';
        }
        deps.push(dep);
    }
    return deps;
}
function extractRegistries(pyprojectfile) {
    const sources = pyprojectfile.tool?.poetry?.source;
    if (!Array.isArray(sources) || sources.length === 0) {
        return undefined;
    }
    const registryUrls = new Set();
    for (const source of sources) {
        if (source.url) {
            registryUrls.add(source.url);
        }
    }
    registryUrls.add(process.env.PIP_INDEX_URL ?? 'https://pypi.org/pypi/');
    return Array.from(registryUrls);
}
async function extractPackageFile(content, packageFile) {
    logger_1.logger.trace(`poetry.extractPackageFile(${packageFile})`);
    let pyprojectfile;
    try {
        pyprojectfile = (0, toml_1.parse)(content);
    }
    catch (err) {
        logger_1.logger.debug({ err, packageFile }, 'Error parsing pyproject.toml file');
        return null;
    }
    if (!pyprojectfile.tool?.poetry) {
        logger_1.logger.debug({ packageFile }, `contains no poetry section`);
        return null;
    }
    // handle the lockfile
    const lockfileName = (0, fs_1.getSiblingFileName)(packageFile, 'poetry.lock');
    // TODO #22198
    const lockContents = (await (0, fs_1.readLocalFile)(lockfileName, 'utf8'));
    const lockfileMapping = (0, locked_version_1.extractLockFileEntries)(lockContents);
    const deps = [
        ...extractFromDependenciesSection(pyprojectfile, 'dependencies', lockfileMapping),
        ...extractFromDependenciesSection(pyprojectfile, 'dev-dependencies', lockfileMapping),
        ...extractFromDependenciesSection(pyprojectfile, 'extras', lockfileMapping),
        ...Object.keys(pyprojectfile.tool?.poetry?.group ?? []).flatMap((group) => extractFromDependenciesGroupSection(pyprojectfile, group, lockfileMapping)),
    ];
    if (!deps.length) {
        return null;
    }
    const extractedConstraints = {};
    if (is_1.default.nonEmptyString(pyprojectfile.tool?.poetry?.dependencies?.python)) {
        extractedConstraints.python =
            pyprojectfile.tool?.poetry?.dependencies?.python;
    }
    const res = {
        deps,
        registryUrls: extractRegistries(pyprojectfile),
        extractedConstraints,
    };
    // Try poetry.lock first
    let lockFile = (0, fs_1.getSiblingFileName)(packageFile, 'poetry.lock');
    // istanbul ignore next
    if (await (0, fs_1.localPathExists)(lockFile)) {
        res.lockFiles = [lockFile];
    }
    else {
        // Try pyproject.lock next
        lockFile = (0, fs_1.getSiblingFileName)(packageFile, 'pyproject.lock');
        if (await (0, fs_1.localPathExists)(lockFile)) {
            res.lockFiles = [lockFile];
        }
    }
    return res;
}
exports.extractPackageFile = extractPackageFile;
function extractGithubPackageName(url) {
    const parsedUrl = (0, url_1.parseGitUrl)(url);
    if (parsedUrl.source !== 'github.com') {
        return null;
    }
    return `${parsedUrl.owner}/${parsedUrl.name}`;
}
//# sourceMappingURL=extract.js.map