"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.shouldDeleteHomepage = exports.addMetaData = exports.normalizeDate = exports.massageGithubUrl = exports.massageUrl = void 0;
const tslib_1 = require("tslib");
const is_1 = tslib_1.__importDefault(require("@sindresorhus/is"));
const github_url_from_git_1 = tslib_1.__importDefault(require("github-url-from-git"));
const luxon_1 = require("luxon");
const common_1 = require("../../util/common");
const url_1 = require("../../util/git/url");
const hostRules = tslib_1.__importStar(require("../../util/host-rules"));
const regex_1 = require("../../util/regex");
const url_2 = require("../../util/url");
const metadata_manual_1 = require("./metadata-manual");
const githubPages = (0, regex_1.regEx)('^https://([^.]+).github.com/([^/]+)$');
const gitPrefix = (0, regex_1.regEx)('^git:/?/?');
function massageUrl(sourceUrl) {
    // Replace git@ sourceUrl with https so hostname can be parsed
    const massagedUrl = massageGitAtUrl(sourceUrl);
    // Check if URL is valid
    const parsedUrl = (0, url_2.parseUrl)(massagedUrl);
    if (!parsedUrl) {
        return '';
    }
    if ((0, common_1.detectPlatform)(massagedUrl) === 'gitlab') {
        return massageGitlabUrl(sourceUrl);
    }
    return massageGithubUrl(sourceUrl);
}
exports.massageUrl = massageUrl;
function massageGithubUrl(url) {
    const massagedUrl = massageGitAtUrl(url);
    return massagedUrl
        .replace('http:', 'https:')
        .replace('http+git:', 'https:')
        .replace('https+git:', 'https:')
        .replace('ssh://git@', 'https://')
        .replace(gitPrefix, 'https://')
        .replace(githubPages, 'https://github.com/$1/$2')
        .replace('www.github.com', 'github.com')
        .split('/')
        .slice(0, 5)
        .join('/');
}
exports.massageGithubUrl = massageGithubUrl;
function massageGitlabUrl(url) {
    const massagedUrl = massageGitAtUrl(url);
    return massagedUrl
        .replace('http:', 'https:')
        .replace(gitPrefix, 'https://')
        .replace((0, regex_1.regEx)(/\/tree\/.*$/i), '')
        .replace((0, regex_1.regEx)(/\/$/i), '')
        .replace('.git', '');
}
function massageGitAtUrl(url) {
    let massagedUrl = url;
    if (url.startsWith('git@')) {
        massagedUrl = url.replace(':', '/').replace('git@', 'https://');
    }
    return massagedUrl;
}
function normalizeDate(input) {
    if (typeof input === 'number' &&
        !Number.isNaN(input) &&
        input > 0 &&
        input <= Date.now() + 24 * 60 * 60 * 1000) {
        return new Date(input).toISOString();
    }
    if (typeof input === 'string') {
        // `Date.parse()` is more permissive, but it assumes local time zone
        // for inputs like `2021-01-01`.
        //
        // Here we try to parse with default UTC with fallback to `Date.parse()`.
        //
        // It allows us not to care about machine timezones so much, though
        // some misinterpretation is still possible, but only if both:
        //
        //   1. Renovate machine is configured for non-UTC zone
        //   2. Format of `input` is very exotic
        //      (from `DateTime.fromISO()` perspective)
        //
        let luxonDate = luxon_1.DateTime.fromISO(input, { zone: 'UTC' });
        if (luxonDate.isValid) {
            return luxonDate.toISO();
        }
        luxonDate = luxon_1.DateTime.fromFormat(input, 'yyyyMMddHHmmss', {
            zone: 'UTC',
        });
        if (luxonDate.isValid) {
            return luxonDate.toISO();
        }
        return normalizeDate(Date.parse(input));
    }
    if (input instanceof Date) {
        return input.toISOString();
    }
    return null;
}
exports.normalizeDate = normalizeDate;
function massageTimestamps(dep) {
    for (const release of dep.releases || []) {
        let { releaseTimestamp } = release;
        delete release.releaseTimestamp;
        releaseTimestamp = normalizeDate(releaseTimestamp);
        if (releaseTimestamp) {
            release.releaseTimestamp = releaseTimestamp;
        }
    }
}
function addMetaData(dep, datasource, packageName) {
    massageTimestamps(dep);
    const packageNameLowercase = packageName.toLowerCase();
    const manualChangelogUrl = metadata_manual_1.manualChangelogUrls[datasource]?.[packageNameLowercase];
    if (manualChangelogUrl) {
        dep.changelogUrl = manualChangelogUrl;
    }
    const manualSourceUrl = metadata_manual_1.manualSourceUrls[datasource]?.[packageNameLowercase];
    if (manualSourceUrl) {
        dep.sourceUrl = manualSourceUrl;
    }
    if (dep.sourceUrl && !dep.sourceDirectory) {
        try {
            const parsed = (0, url_1.parseGitUrl)(dep.sourceUrl);
            if (parsed.filepathtype === 'tree' && parsed.filepath !== '') {
                dep.sourceUrl = parsed.toString();
                dep.sourceDirectory = parsed.filepath;
            }
        }
        catch (err) {
            // ignore invalid urls
        }
    }
    if (!dep.sourceUrl &&
        dep.changelogUrl &&
        (0, common_1.detectPlatform)(dep.changelogUrl) === 'github') {
        dep.sourceUrl = dep.changelogUrl;
    }
    if (!dep.sourceUrl && dep.homepage) {
        const platform = (0, common_1.detectPlatform)(dep.homepage);
        if (platform === 'github' || platform === 'gitlab') {
            dep.sourceUrl = dep.homepage;
        }
    }
    const extraBaseUrls = [];
    // istanbul ignore next
    hostRules.hosts({ hostType: 'github' }).forEach((host) => {
        extraBaseUrls.push(host, `gist.${host}`);
    });
    extraBaseUrls.push('gitlab.com');
    if (dep.sourceUrl) {
        const massagedUrl = massageUrl(dep.sourceUrl);
        if (is_1.default.emptyString(massagedUrl)) {
            delete dep.sourceUrl;
        }
        else {
            // try massaging it
            dep.sourceUrl =
                (0, github_url_from_git_1.default)(massagedUrl, {
                    extraBaseUrls,
                }) || dep.sourceUrl;
        }
    }
    if (shouldDeleteHomepage(dep.sourceUrl, dep.homepage)) {
        delete dep.homepage;
    }
    // Clean up any empty urls
    const urlKeys = [
        'homepage',
        'sourceUrl',
        'changelogUrl',
        'dependencyUrl',
    ];
    for (const urlKey of urlKeys) {
        const urlVal = dep[urlKey];
        if (is_1.default.string(urlVal) && (0, url_2.validateUrl)(urlVal.trim())) {
            dep[urlKey] = urlVal.trim();
        }
        else {
            delete dep[urlKey];
        }
    }
}
exports.addMetaData = addMetaData;
/**
 * Returns true if
 * 1. it's a github or gitlab url and not a path within the repo.
 * 2. it's equal to sourceURl
 * @param sourceUrl
 * @param homepage
 */
function shouldDeleteHomepage(sourceUrl, homepage) {
    if (is_1.default.nullOrUndefined(sourceUrl) || is_1.default.undefined(homepage)) {
        return false;
    }
    const massagedSourceUrl = massageUrl(sourceUrl);
    const platform = (0, common_1.detectPlatform)(homepage);
    if (platform === 'github' || platform === 'gitlab') {
        const sourceUrlParsed = (0, url_2.parseUrl)(massagedSourceUrl);
        if (is_1.default.nullOrUndefined(sourceUrlParsed)) {
            return false;
        }
        const homepageParsed = (0, url_2.parseUrl)(homepage);
        return (homepageParsed !== null &&
            (0, url_2.trimTrailingSlash)(homepageParsed.pathname) ===
                (0, url_2.trimTrailingSlash)(sourceUrlParsed.pathname));
    }
    return massagedSourceUrl === homepage;
}
exports.shouldDeleteHomepage = shouldDeleteHomepage;
//# sourceMappingURL=metadata.js.map