"use strict";
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.valueType = exports.getMutability = exports.XML = exports.isSchemaObject = exports.isJsonType = exports.JsonType = exports.Discriminator = exports.getVirtualPropertyFromPropertyName = exports.getAllVirtualProperties = exports.getAllPublicVirtualPropertiesForSdkWithoutInherited = exports.getAllPublicVirtualPropertiesForSdk = exports.getAllPublicVirtualProperties = exports.getAllProperties = exports.getPolymorphicBases = exports.Purpose = void 0;
const extensions_1 = require("./extensions");
const linq_1 = require("@azure-tools/linq");
const codemodel_1 = require("@autorest/codemodel");
var Purpose;
(function (Purpose) {
    Purpose["Header"] = "Header";
})(Purpose || (exports.Purpose = Purpose = {}));
// export class Schema extends Extensions implements Schema {
//   public details: LanguageDetails<SchemaDetails>;
//   public required = new Array<string>();
//   public enum = new Array<any>();
//   public allOf = new Array<Schema>();
//   public oneOf = new Array<Schema>();
//   public anyOf = new Array<Schema>();
//   public properties = new Dictionary<Property>();
//   public extensions = new Dictionary<any>();
//   constructor(name: string, initializer?: DeepPartial<Schema>) {
//     super();
//     this.details = {
//       default: {
//         uid: `schema:${uid()}`,
//         description: '',
//         name
//       }
//     };
//     this.apply(initializer);
//   }
// }
function getPolymorphicBases(schema) {
    var _a;
    // are any of my parents polymorphic directly, or any of their parents?
    return [...(0, linq_1.values)((_a = schema.parents) === null || _a === void 0 ? void 0 : _a.all).where(parent => parent.discriminator ? true : false)];
}
exports.getPolymorphicBases = getPolymorphicBases;
function getAllProperties(schema) {
    if ((0, codemodel_1.isObjectSchema)(schema)) {
        return [...(0, linq_1.values)(schema.parents ? schema.parents.immediate : []).selectMany(getAllProperties), ...(0, linq_1.values)(schema.properties)];
    }
    else {
        return [];
    }
}
exports.getAllProperties = getAllProperties;
function getAllPublicVirtualProperties(virtualProperties) {
    const props = virtualProperties || {
        owned: [],
        inherited: [],
        inlined: []
    };
    return (0, linq_1.values)(props.owned, props.inherited, props.inlined).where(each => !each.private).toArray();
}
exports.getAllPublicVirtualProperties = getAllPublicVirtualProperties;
function getAllPublicVirtualPropertiesForSdk(virtualProperties) {
    const props = virtualProperties || {
        owned: [],
        inherited: [],
        inlined: []
    };
    // meanwhile we need to skip discriminator
    return (0, linq_1.values)(props.inherited, props.owned, props.inlined).where(each => !each.private && !each.property.isDiscriminator).toArray();
}
exports.getAllPublicVirtualPropertiesForSdk = getAllPublicVirtualPropertiesForSdk;
function getAllPublicVirtualPropertiesForSdkWithoutInherited(virtualProperties) {
    const props = virtualProperties || {
        owned: [],
        inherited: [],
        inlined: []
    };
    return (0, linq_1.values)(props.owned, props.inlined).where(each => !each.private && !each.property.isDiscriminator).toArray();
}
exports.getAllPublicVirtualPropertiesForSdkWithoutInherited = getAllPublicVirtualPropertiesForSdkWithoutInherited;
function getAllVirtualProperties(virtualProperties) {
    const props = virtualProperties || {
        owned: [],
        inherited: [],
        inlined: []
    };
    return (0, linq_1.values)(props.owned, props.inherited, props.inlined).toArray();
}
exports.getAllVirtualProperties = getAllVirtualProperties;
function getVirtualPropertyFromPropertyName(virtualProperties, propertyName) {
    const props = virtualProperties || {
        owned: [],
        inherited: [],
        inlined: []
    };
    return (0, linq_1.values)([...(0, linq_1.values)(props.owned), ...(0, linq_1.values)(props.inherited), ...(0, linq_1.values)(props.inlined)]).first(each => each.property.serializedName === propertyName);
}
exports.getVirtualPropertyFromPropertyName = getVirtualPropertyFromPropertyName;
// export interface Property extends Extensions {
//   details: LanguageDetails<PropertyDetails>;
//   /** description can be on the property reference, so that properties can have a description different from the type description. */
//   description?: string;
//   schema: Schema;
// }
// export class Property extends Extensions implements Property {
//   public serializedName: string;
//   public details: LanguageDetails<PropertyDetails>;
//   public extensions = new Dictionary<any>();
//   constructor(name: string, initializer?: DeepPartial<Property>) {
//     super();
//     this.serializedName = name;
//     this.details = {
//       default: {
//         readOnly: false,
//         uid: `property:${uid()}`,
//         description: initializer?.description || '',
//         name,
//         required: false
//       }
//     };
//     this.apply(initializer);
//   }
// }
class Discriminator extends extensions_1.Extensions {
    constructor(propertyName, initializer) {
        super();
        this.propertyName = propertyName;
        this.extensions = new linq_1.Dictionary();
        this.mapping = new linq_1.Dictionary();
        this.apply(initializer);
    }
}
exports.Discriminator = Discriminator;
var JsonType;
(function (JsonType) {
    JsonType["Array"] = "array";
    JsonType["Boolean"] = "boolean";
    JsonType["Integer"] = "integer";
    JsonType["Number"] = "number";
    JsonType["Object"] = "object";
    JsonType["String"] = "string";
})(JsonType || (exports.JsonType = JsonType = {}));
function isJsonType(type, schema) {
    return schema ? schema.type === codemodel_1.SchemaType.Object : false;
}
exports.isJsonType = isJsonType;
function isSchemaObject(schema) {
    return isJsonType(JsonType.Object, schema);
}
exports.isSchemaObject = isSchemaObject;
class XML extends extensions_1.Extensions {
    constructor(initializer) {
        super();
        this.extensions = new linq_1.Dictionary();
        this.attribute = false;
        this.wrapped = false;
        this.apply(initializer);
    }
}
exports.XML = XML;
// export interface Schema extends Extensions {
//   details: LanguageDetails<SchemaDetails>;
//   /* common properties */
//   type?: JsonType;
//   title?: string;
//   description?: string;
//   format?: string;
//   nullable: boolean;
//   readOnly: boolean;
//   writeOnly: boolean;
//   deprecated: boolean;
//   required: Array<string>;
//   /* number restrictions */
//   multipleOf?: number;
//   maximum?: number;
//   exclusiveMaximum?: boolean;
//   minimum?: number;
//   exclusiveMinimum?: boolean;
//   /* string restrictions */
//   maxLength?: number;
//   minLength?: number;
//   pattern?: string; // regex
//   /* array restrictions */
//   maxItems?: number;
//   minItems?: number;
//   uniqueItems?: boolean;
//   /* object restrictions */
//   maxProperties?: number;
//   minProperties?: number;
//   /* unbounded properties */
//   example?: any;
//   default?: any;
//   /* Properties that are objects */
//   discriminator?: Discriminator;
//   externalDocs?: ExternalDocumentation;
//   xml?: XML;
//   /* Properties that are collections of things that are not references */
//   enum: Array<any>;
//   /* properties with potential references */
//   not?: Schema;
//   allOf: Array<Schema>;
//   oneOf: Array<Schema>;
//   anyOf: Array<Schema>;
//   items?: Schema;
//   properties: Dictionary<Property>;
//   additionalProperties?: boolean | Schema;
// }
function getMutability(property) {
    const mutability = { create: true, update: true, read: true };
    if (property.extensions && property.extensions['x-ms-mutability']) {
        const mt = property.extensions['x-ms-mutability'];
        mutability.create = mt.includes('create') ? true : false;
        mutability.update = mt.includes('update') ? true : false;
        mutability.read = mt.includes('read') ? true : false;
    }
    return mutability;
}
exports.getMutability = getMutability;
// check whether it is value type
function valueType(type) {
    if (['boolean', 'integer', 'number', 'unixtime', 'duration', 'uuid', 'date-time', 'date'].includes(type)) {
        return true;
    }
    return false;
}
exports.valueType = valueType;
//# sourceMappingURL=schema.js.map