"use strict";
// Copyright 2017-2020 @polkadot/metadata authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const types_1 = require("../../../types/codec/types");
const create_1 = require("../../../types/codec/create");
const flattenUniq_1 = __importDefault(require("./flattenUniq"));
/** @internal */
function extractTypes(types) {
    return types.map((type) => {
        const decoded = create_1.getTypeDef(type);
        switch (decoded.info) {
            case types_1.TypeDefInfo.Plain:
                return decoded.type;
            case types_1.TypeDefInfo.Compact:
            case types_1.TypeDefInfo.Option:
            case types_1.TypeDefInfo.Vec:
                return extractTypes([decoded.sub.type]);
            case types_1.TypeDefInfo.VecFixed:
                return extractTypes([decoded.ext.type]);
            case types_1.TypeDefInfo.BTreeMap:
            case types_1.TypeDefInfo.BTreeSet:
            case types_1.TypeDefInfo.Result:
            case types_1.TypeDefInfo.Tuple:
                return extractTypes(decoded.sub.map((sub) => sub.type));
            default:
                throw new Error(`Unhandled: Unable to create and validate type from ${type}`);
        }
    });
}
/** @internal */
function validateTypes(registry, types, throwError) {
    const missing = flattenUniq_1.default(extractTypes(types)).filter((type) => !registry.hasType(type));
    if (missing.length !== 0) {
        const message = `Unknown types found, no types for ${missing}`;
        if (throwError) {
            throw new Error(message);
        }
        else {
            console.warn(message);
        }
    }
}
exports.default = validateTypes;
