"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TokenListContainer = exports.TokenListProvider = exports.StaticTokenListResolutionStrategy = exports.SolanaTokenListResolutionStrategy = exports.Strategy = exports.CDNTokenListResolutionStrategy = exports.GitHubTokenListResolutionStrategy = exports.CLUSTER_SLUGS = exports.ENV = void 0;
const cross_fetch_1 = require("cross-fetch");
const solana_tokenlist_json_1 = __importDefault(require("./../tokens/solana.tokenlist.json"));
var ENV;
(function (ENV) {
    ENV[ENV["MainnetBeta"] = 101] = "MainnetBeta";
    ENV[ENV["Testnet"] = 102] = "Testnet";
    ENV[ENV["Devnet"] = 103] = "Devnet";
})(ENV = exports.ENV || (exports.ENV = {}));
exports.CLUSTER_SLUGS = {
    'mainnet-beta': ENV.MainnetBeta,
    testnet: ENV.Testnet,
    devnet: ENV.Devnet,
};
class GitHubTokenListResolutionStrategy {
    constructor() {
        this.repositories = [
            'https://raw.githubusercontent.com/brave/solana-token-list/main/src/tokens/solana.tokenlist.json',
        ];
        this.resolve = () => {
            return queryJsonFiles(this.repositories);
        };
    }
}
exports.GitHubTokenListResolutionStrategy = GitHubTokenListResolutionStrategy;
class CDNTokenListResolutionStrategy {
    constructor() {
        this.repositories = [
            'https://cdn.jsdelivr.net/gh/brave/solana-token-list@main/src/tokens/solana.tokenlist.json',
        ];
        this.resolve = () => {
            return queryJsonFiles(this.repositories);
        };
    }
}
exports.CDNTokenListResolutionStrategy = CDNTokenListResolutionStrategy;
const queryJsonFiles = async (files) => {
    const responses = (await Promise.all(files.map(async (repo) => {
        try {
            const response = await cross_fetch_1.fetch(repo);
            const json = (await response.json());
            return json;
        }
        catch (_a) {
            console.info(`@brave/spl-token-registry: falling back to static repository.`);
            return solana_tokenlist_json_1.default;
        }
    })));
    return responses
        .map((tokenlist) => tokenlist.tokens)
        .reduce((acc, arr) => acc.concat(arr), []);
};
var Strategy;
(function (Strategy) {
    Strategy["GitHub"] = "GitHub";
    Strategy["Static"] = "Static";
    Strategy["Solana"] = "Solana";
    Strategy["CDN"] = "CDN";
})(Strategy = exports.Strategy || (exports.Strategy = {}));
class SolanaTokenListResolutionStrategy {
    constructor() {
        this.resolve = () => {
            throw new Error(`Not Implemented Yet.`);
        };
    }
}
exports.SolanaTokenListResolutionStrategy = SolanaTokenListResolutionStrategy;
class StaticTokenListResolutionStrategy {
    constructor() {
        this.resolve = () => {
            return solana_tokenlist_json_1.default.tokens;
        };
    }
}
exports.StaticTokenListResolutionStrategy = StaticTokenListResolutionStrategy;
class TokenListProvider {
    constructor() {
        this.resolve = async (strategy = Strategy.CDN) => {
            return new TokenListContainer(await TokenListProvider.strategies[strategy].resolve());
        };
    }
}
exports.TokenListProvider = TokenListProvider;
TokenListProvider.strategies = {
    [Strategy.GitHub]: new GitHubTokenListResolutionStrategy(),
    [Strategy.Static]: new StaticTokenListResolutionStrategy(),
    [Strategy.Solana]: new SolanaTokenListResolutionStrategy(),
    [Strategy.CDN]: new CDNTokenListResolutionStrategy(),
};
class TokenListContainer {
    constructor(tokenList) {
        this.tokenList = tokenList;
        this.filterByTag = (tag) => {
            return new TokenListContainer(this.tokenList.filter((item) => (item.tags || []).includes(tag)));
        };
        this.filterByChainId = (chainId) => {
            return new TokenListContainer(this.tokenList.filter((item) => item.chainId === chainId));
        };
        this.excludeByChainId = (chainId) => {
            return new TokenListContainer(this.tokenList.filter((item) => item.chainId !== chainId));
        };
        this.excludeByTag = (tag) => {
            return new TokenListContainer(this.tokenList.filter((item) => !(item.tags || []).includes(tag)));
        };
        this.filterByClusterSlug = (slug) => {
            if (slug in exports.CLUSTER_SLUGS) {
                return this.filterByChainId(exports.CLUSTER_SLUGS[slug]);
            }
            throw new Error(`Unknown slug: ${slug}, please use one of ${Object.keys(exports.CLUSTER_SLUGS)}`);
        };
        this.getList = () => {
            return this.tokenList;
        };
    }
}
exports.TokenListContainer = TokenListContainer;
//# sourceMappingURL=data:application/json;base64, 