"use strict";
/*
 * Copyright © 2020 Atomist, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.addThirdPartyLicenseTransform = exports.addThirdPartyLicense = exports.AddThirdPartyLicenseAutofix = void 0;
const fs = require("fs-extra");
const lc = require("license-checker");
const _ = require("lodash");
const path = require("path");
const spdx = require("spdx-license-list");
const util_1 = require("util");
const StringCapturingProgressLog_1 = require("../../../api-helper/log/StringCapturingProgressLog");
const child_process_1 = require("../../../api-helper/misc/child_process");
const commonPushTests_1 = require("../../../api/mapping/support/commonPushTests");
const pushTestUtils_1 = require("../../../api/mapping/support/pushTestUtils");
const nodePushTests_1 = require("../pushtest/nodePushTests");
const LicenseMapping = {
    "Apache 2.0": "Apache-2.0",
};
const LicenseFileName = "legal/THIRD_PARTY.md";
const GitattributesFileName = ".gitattributes";
const LicenseTableHeader = `| Name | Version | Publisher | Repository |
|------|---------|-----------|------------|`;
const SummaryTableHadler = `| License | Count |
|---------|-------|`;
exports.AddThirdPartyLicenseAutofix = addThirdPartyLicense(pushTestUtils_1.allSatisfied(nodePushTests_1.IsNode, commonPushTests_1.ToDefaultBranch));
function addThirdPartyLicense(pushTest) {
    return {
        name: "Third party licenses",
        pushTest,
        transform: addThirdPartyLicenseTransform(),
    };
}
exports.addThirdPartyLicense = addThirdPartyLicense;
function addThirdPartyLicenseTransform() {
    return async (p) => {
        const cwd = p.baseDir;
        const pj = JSON.parse((await fs.readFile(path.join(cwd, "package.json"))).toString());
        const ownModule = `${pj.name}@${pj.version}`;
        if (!(await p.hasDirectory("node_modules"))) {
            const result = await child_process_1.spawnLog("npm", ["ci"], {
                cwd,
                log: new StringCapturingProgressLog_1.StringCapturingProgressLog(),
            });
            if (result && result.code !== 0) {
                return p;
            }
        }
        const json = await util_1.promisify(lc.init)({
            start: cwd,
            production: true,
        });
        const grouped = {};
        _.forEach(json, (v, k) => {
            if (k === ownModule) {
                return;
            }
            let licenses = v.licenses;
            if (!Array.isArray(licenses)) {
                if (licenses.endsWith("*")) {
                    licenses = licenses.slice(0, -1);
                }
                if (licenses.startsWith("(") && licenses.endsWith(")")) {
                    licenses = licenses.slice(1, -1);
                }
                licenses = [...licenses.split(" OR ")];
            }
            licenses.forEach(l => {
                let license = l;
                if (LicenseMapping.hasOwnProperty(license)) {
                    license = LicenseMapping[license];
                }
                if (grouped.hasOwnProperty(license)) {
                    grouped[license] = [
                        ...grouped[license],
                        Object.assign(Object.assign({}, v), { name: k }),
                    ];
                }
                else {
                    grouped[license] = [
                        Object.assign(Object.assign({}, v), { name: k }),
                    ];
                }
            });
        });
        const summary = [];
        const counts = _.mapValues(grouped, l => l.length);
        for (const l in counts) {
            if (counts.hasOwnProperty(l)) {
                const anchor = l
                    .toLocaleLowerCase()
                    .replace(/ /g, "-")
                    .replace(/\./g, "")
                    .replace(/:/g, "")
                    .replace(/\//g, "");
                summary.push(`|[${l}](#${anchor})|${counts[l]}|`);
            }
        }
        const details = [];
        // tslint:disable-next-line:no-inferred-empty-object-type
        _.forEach(grouped, (v, k) => {
            const deps = v.map(dep => {
                const ix = dep.name.lastIndexOf("@");
                const name = dep.name.slice(0, ix);
                const version = dep.name.slice(ix + 1);
                return `|\`${name}\`|\`${version}\`|${dep.publisher ? dep.publisher : ""}|${dep.repository ? `[${dep.repository}](${dep.repository})` : ""}|`;
            });
            let ld = "";
            if (spdx[k]) {
                ld = `${spdx[k].name} - [${spdx[k].url}](${spdx[k].url})\n`;
            }
            details.push(`
#### ${k}
${ld}
${LicenseTableHeader}
${deps.join("\n")}`);
        });
        const lic = spdx[pj.license]
            ? `

\`${pj.name}\` is licensed under ${spdx[pj.license].name} - [${spdx[pj.license].url}](${spdx[pj.license].url}).`
            : "";
        const content = `# \`${pj.name}\`${lic}

This page details all runtime OSS dependencies of \`${pj.name}\`.

## Licenses

### Summary

${SummaryTableHadler}
${summary.sort((s1, s2) => s1.localeCompare(s2)).join("\n")}
${details.sort((s1, s2) => s1.localeCompare(s2)).join("\n")}

## Contact

Please send any questions or inquires to [oss@atomist.com](mailto:oss@atomist.com).

---

Created by [Atomist][atomist].
Need Help?  [Join our Slack team][slack].

[atomist]: https://atomist.com/ (Atomist - Development Automation)
[slack]: https://join.atomist.com/ (Atomist Community Slack)
`;
        await addGitattribute(p);
        await p.deleteDirectory("node_modules");
        await p.addFile(LicenseFileName, content);
        return p;
    };
}
exports.addThirdPartyLicenseTransform = addThirdPartyLicenseTransform;
async function addGitattribute(p) {
    const attribute = `${LicenseFileName} linguist-generated=true
`;
    const ga = await p.getFile(GitattributesFileName);
    if (ga) {
        let c = await ga.getContent();
        if (!c.includes(LicenseFileName)) {
            c += `
${attribute}`;
            await ga.setContent(c);
        }
    }
    else {
        await p.addFile(GitattributesFileName, attribute);
    }
}
//# sourceMappingURL=thirdPartyLicense.js.map