"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
 * @license
 * Copyright Google Inc. All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.io/license
 */
const interface_1 = require("../interface");
const allTypes = ['string', 'integer', 'number', 'object', 'array', 'boolean', 'null'];
function getTypesOfSchema(schema) {
    if (!schema) {
        return new Set();
    }
    if (schema === true) {
        return new Set(allTypes);
    }
    let potentials;
    if (typeof schema.type === 'string') {
        potentials = new Set([schema.type]);
    }
    else if (Array.isArray(schema.type)) {
        potentials = new Set(schema.type);
    }
    else if (interface_1.isJsonArray(schema.enum)) {
        potentials = new Set();
        // Gather the type of each enum values, and use that as a starter for potential types.
        for (const v of schema.enum) {
            switch (typeof v) {
                case 'string':
                case 'number':
                case 'boolean':
                    potentials.add(typeof v);
                    break;
                case 'object':
                    if (Array.isArray(v)) {
                        potentials.add('array');
                    }
                    else if (v === null) {
                        potentials.add('null');
                    }
                    else {
                        potentials.add('object');
                    }
                    break;
            }
        }
    }
    else {
        potentials = new Set(allTypes);
    }
    if (interface_1.isJsonObject(schema.not)) {
        const notTypes = getTypesOfSchema(schema.not);
        potentials = new Set([...potentials].filter(p => !notTypes.has(p)));
    }
    if (Array.isArray(schema.allOf)) {
        for (const sub of schema.allOf) {
            const types = getTypesOfSchema(sub);
            potentials = new Set([...potentials].filter(p => types.has(p)));
        }
    }
    if (Array.isArray(schema.oneOf)) {
        let options = new Set();
        for (const sub of schema.oneOf) {
            const types = getTypesOfSchema(sub);
            options = new Set([...options, ...types]);
        }
        potentials = new Set([...potentials].filter(p => options.has(p)));
    }
    if (Array.isArray(schema.anyOf)) {
        let options = new Set();
        for (const sub of schema.anyOf) {
            const types = getTypesOfSchema(sub);
            options = new Set([...options, ...types]);
        }
        potentials = new Set([...potentials].filter(p => options.has(p)));
    }
    if (schema.properties) {
        potentials.add('object');
    }
    else if (schema.items) {
        potentials.add('array');
    }
    return potentials;
}
exports.getTypesOfSchema = getTypesOfSchema;
