"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.calculateDependencies = exports.mapApplicationV2ToApp = exports.getDependents = exports.getDependencies = exports.whitelistDependencies = void 0;
// polyfill the unfinished support of apps logic
const semver_1 = __importDefault(require("semver"));
const cryptoassets_1 = require("@ledgerhq/cryptoassets");
const types_live_1 = require("@ledgerhq/types-live");
const directDep = {};
const reverseDep = {};
// whitelist dependencies
exports.whitelistDependencies = [
    "Decred",
    "Decred Test",
    "Bitcoin",
    "Bitcoin Test",
    "Zcash",
    "Avalanche",
    "Avalanche Test",
];
function declareDep(name, dep) {
    if (exports.whitelistDependencies.includes(name)) {
        return;
    }
    directDep[name] = (directDep[name] || []).concat(dep);
    reverseDep[dep] = (reverseDep[dep] || []).concat(name);
}
// extra dependencies
[
    ["LBRY", "Bitcoin"],
    ["Ravencoin", "Bitcoin"],
    ["Resistance", "Bitcoin"],
    ["ZenCash", "Bitcoin"],
    ["[ L ] Market", "Ethereum"],
    ["1inch", "Ethereum"],
    ["Aave", "Ethereum"],
    ["Alkemi", "Ethereum"],
    ["Angle", "Ethereum"],
    ["APWine", "Ethereum"],
    ["ArtBlocks", "Ethereum"],
    ["ARTIS sigma1", "Ethereum"],
    ["Astar EVM", "Ethereum"],
    ["Binance Smart Chain", "Ethereum"],
    ["cBridge", "Ethereum"],
    ["Cometh", "Ethereum"],
    ["Compound", "Ethereum"],
    ["DODO", "Ethereum"],
    ["EnergyWebChain", "Ethereum"],
    ["Euler", "Ethereum"],
    ["Flare", "Ethereum"],
    ["Harvest", "Ethereum"],
    ["Kiln", "Ethereum"],
    ["kUSD", "Ethereum"],
    ["Lido", "Ethereum"],
    ["Morpho", "Ethereum"],
    ["Moonbeam", "Ethereum"],
    ["Moonriver", "Ethereum"],
    ["Nested", "Ethereum"],
    ["Oasys", "Ethereum"],
    ["OlympusDAO", "Ethereum"],
    ["Opensea", "Ethereum"],
    ["Paraswap", "Ethereum"],
    ["POAP", "Ethereum"],
    ["Polygon", "Ethereum"],
    ["Rarible", "Ethereum"],
    ["Ricochet", "Ethereum"],
    ["RocketPool", "Ethereum"],
    ["RSK Test", "Ethereum"],
    ["RSK", "Ethereum"],
    ["Shiden EVM", "Ethereum"],
    ["Spool", "Ethereum"],
    ["Staderlabs", "Ethereum"],
    ["StakeDAO", "Ethereum"],
    ["ThunderCore", "Ethereum"],
    ["Volta", "Ethereum"],
    ["XDC Network", "Ethereum"],
    ["Yearn", "Ethereum"],
].forEach(([name, dep]) => declareDep(name, dep));
// Nb Starting on version 2.1.0 Bitcoin family apps no longer depend on
// Bitcoin as a library. We will soon have the dependencies resolved from
// back-end but until then we need to manually remove them.
const versionBasedWhitelistDependencies = {
    Bitcoin: "2.1.0",
};
const getDependencies = (appName, appVersion) => {
    const maybeDirectDep = directDep[appName] || [];
    if (!appVersion || !maybeDirectDep.length) {
        return maybeDirectDep;
    }
    // If we don't have any direct dependencies, or the caller didn't
    // provide `appVersion` to compare against, we can skip the filter
    return maybeDirectDep.filter((dep) => {
        const maybeDep = versionBasedWhitelistDependencies[dep];
        return !maybeDep || semver_1.default.lt(semver_1.default.coerce(appVersion) ?? "", maybeDep);
    });
};
exports.getDependencies = getDependencies;
const getDependents = (appName) => reverseDep[appName] || [];
exports.getDependents = getDependents;
function matchAppNameAndCryptoCurrency(appName, crypto) {
    if (appName === "Ethereum") {
        return crypto.id === "ethereum";
    }
    return appName.toLowerCase() === crypto.managerAppName.toLowerCase();
}
const getCurrencyIdFromAppName = (appName) => {
    const crypto = 
    // try to find the "official" currency when possible (2 currencies can have the same manager app and ticker)
    (0, cryptoassets_1.listCryptoCurrencies)(true, true).find(c => c.name === appName || matchAppNameAndCryptoCurrency(appName, c));
    return crypto?.id;
};
/**
 * Due to the schema returned by the Manager API we need this key remapping and
 * slight polyfill because we are not the only consumers of the API and they
 * can't give us exactly what we need. It's a pity but it's our pity.
 * @param param ApplicationV2
 * @returns App
 */
const mapApplicationV2ToApp = ({ versionId: id, versionName: name, versionDisplayName: displayName, firmwareKey: firmware_key, // No point in refactoring since api wont change.
deleteKey: delete_key, applicationType: type, parentName, currencyId, ...rest }) => ({
    id,
    name,
    displayName,
    firmware_key,
    delete_key,
    dependencies: parentName ? [parentName] : [],
    indexOfMarketCap: -1,
    type: name === "Exchange"
        ? types_live_1.AppType.swap
        : Object.values(types_live_1.AppType).includes(type)
            ? type
            : types_live_1.AppType.currency,
    ...rest,
    currencyId: (0, cryptoassets_1.findCryptoCurrencyById)(currencyId) ? currencyId : getCurrencyIdFromAppName(name),
});
exports.mapApplicationV2ToApp = mapApplicationV2ToApp;
const calculateDependencies = () => {
    (0, cryptoassets_1.listCryptoCurrencies)(true, true).forEach((currency) => {
        if (!currency.managerAppName)
            return; // no app for this currency
        /**
         * For currencies from the evm family that use a specific app (other than the Ethereum app),
         * the currency ID of the parent app is ethereum and not the family name.
         */
        const parentCurrencyId = currency.family === "evm" ? "ethereum" : currency.family;
        const family = (0, cryptoassets_1.findCryptoCurrencyById)(parentCurrencyId);
        if (!family || !family.managerAppName)
            return; // no dep
        if (family.managerAppName === currency.managerAppName)
            return; // same app
        declareDep(currency.managerAppName, family.managerAppName);
        if (!currency.isTestnetFor) {
            declareDep(currency.managerAppName + " Test", family.managerAppName);
        }
    });
};
exports.calculateDependencies = calculateDependencies;
//# sourceMappingURL=polyfill.js.map