var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
/* Generated from Java with JSweet 2.3.7 - http://www.jsweet.org */
import { Library } from '../../Library';
import { ModelUtils } from '../util/ModelUtils';
import { LoggerCompat } from '../../compat/LoggerCompat';
import { NodeCompat } from '../../compat/NodeCompat';
import { OasSchema } from '../../openapi/models/OasSchema';
import { AbstractSchemaInhCommand } from './AbstractSchemaInhCommand';
/**
 * Allows changing the inheritance setting for a schema.  This basically allows changing
 * the usage of "anyOf", "allOf", etc.  The algorithm for this command is as follows:
 *
 * - When switching from "none" to any inheritance mode, any existing properties of the
 * schema will be wrapped in a new schema and added to the new inheritance mode
 * - When switching from any inheritance mode back to "none", any properties in a wrapped
 * schema will be unwrapped and added as properties
 * - When switching from one inheritance mode to another, the list of schemas will be
 * copied over with it (e.g. when going from "allOf" to "anyOf")
 *
 * Challenge: what impact will this have on undo/redo?  Changes made to properties after
 * this command is executed may be lost when this command is undone!
 *
 * @author eric.wittmann@gmail.com
 * @extends AbstractSchemaInhCommand
 * @class
 */
var ChangeSchemaInheritanceCommand = /** @class */ (function (_super) {
    __extends(ChangeSchemaInheritanceCommand, _super);
    function ChangeSchemaInheritanceCommand(schema, inheritanceType) {
        var _this = this;
        if (((schema != null && schema instanceof OasSchema) || schema === null) && ((typeof inheritanceType === 'string') || inheritanceType === null)) {
            var __args = arguments;
            _this = _super.call(this) || this;
            if (_this._schemaPath === undefined)
                _this._schemaPath = null;
            if (_this._newInheritanceType === undefined)
                _this._newInheritanceType = null;
            if (_this._oldInheritanceType === undefined)
                _this._oldInheritanceType = null;
            if (_this._oldSchemas === undefined)
                _this._oldSchemas = null;
            if (_this._schemaPath === undefined)
                _this._schemaPath = null;
            if (_this._newInheritanceType === undefined)
                _this._newInheritanceType = null;
            if (_this._oldInheritanceType === undefined)
                _this._oldInheritanceType = null;
            if (_this._oldSchemas === undefined)
                _this._oldSchemas = null;
            (function () {
                _this._schemaPath = Library.createNodePath(schema);
                _this._newInheritanceType = inheritanceType;
            })();
        }
        else if (schema === undefined && inheritanceType === undefined) {
            var __args = arguments;
            _this = _super.call(this) || this;
            if (_this._schemaPath === undefined)
                _this._schemaPath = null;
            if (_this._newInheritanceType === undefined)
                _this._newInheritanceType = null;
            if (_this._oldInheritanceType === undefined)
                _this._oldInheritanceType = null;
            if (_this._oldSchemas === undefined)
                _this._oldSchemas = null;
            if (_this._schemaPath === undefined)
                _this._schemaPath = null;
            if (_this._newInheritanceType === undefined)
                _this._newInheritanceType = null;
            if (_this._oldInheritanceType === undefined)
                _this._oldInheritanceType = null;
            if (_this._oldSchemas === undefined)
                _this._oldSchemas = null;
        }
        else
            throw new Error('invalid overload');
        return _this;
    }
    /**
     * @see io.apicurio.datamodels.cmd.ICommand#execute(io.apicurio.datamodels.core.models.Document)
     * @param {Document} document
     */
    ChangeSchemaInheritanceCommand.prototype.execute = function (document) {
        LoggerCompat.info("[ChangeSchemaInheritanceCommand] Executing: " + this._newInheritanceType);
        this._oldInheritanceType = null;
        this._oldSchemas = null;
        var schema = this._schemaPath.resolve(document);
        if (this.isNullOrUndefined(schema)) {
            return;
        }
        this._oldInheritanceType = AbstractSchemaInhCommand.getInheritanceType(schema);
        this.switchInheritance(schema, this._oldInheritanceType, this._newInheritanceType, false);
    };
    /**
     * @see io.apicurio.datamodels.cmd.ICommand#undo(io.apicurio.datamodels.core.models.Document)
     * @param {Document} document
     */
    ChangeSchemaInheritanceCommand.prototype.undo = function (document) {
        LoggerCompat.info("[ChangeSchemaInheritanceCommand] Reverting: " + this._oldInheritanceType);
        var schema = this._schemaPath.resolve(document);
        if (this.isNullOrUndefined(schema)) {
            return;
        }
        this.switchInheritance(schema, this._newInheritanceType, this._oldInheritanceType, true);
        if (NodeCompat.equals(AbstractSchemaInhCommand.TYPE_NONE, this._newInheritanceType) && !(this._oldSchemas.length == 0)) {
            this.copySchemaJsTo(this._oldSchemas, schema, this._oldInheritanceType);
        }
    };
    /**
     * Switch the inheritance type.
     * @param {OasSchema} schema
     * @param {string} fromType
     * @param {string} toType
     * @param {boolean} isUndo
     * @private
     */
    /*private*/ ChangeSchemaInheritanceCommand.prototype.switchInheritance = function (schema, fromType, toType, isUndo) {
        var _this = this;
        if (NodeCompat.equals(fromType, toType)) {
            return;
        }
        var schemas = ([]);
        if (NodeCompat.equals(AbstractSchemaInhCommand.TYPE_ALL_OF, fromType)) {
            schemas = schema.allOf;
            schema.allOf = null;
        }
        if (NodeCompat.equals(AbstractSchemaInhCommand.TYPE_ANY_OF, fromType)) {
            var schema30 = schema;
            schemas = schema30.anyOf;
            schema30.anyOf = null;
        }
        if (NodeCompat.equals(AbstractSchemaInhCommand.TYPE_ONE_OF, fromType)) {
            var schema30 = schema;
            schemas = schema30.oneOf;
            schema30.oneOf = null;
        }
        if (NodeCompat.equals(AbstractSchemaInhCommand.TYPE_NONE, toType)) {
            if (!isUndo) {
                this._oldSchemas = ([]);
            }
            schemas.forEach(function (s) {
                if (ModelUtils.isDefined(s.properties)) {
                    _this.moveProperties(s, schema);
                }
                else if (!isUndo) {
                    /* add */ (_this._oldSchemas.push(Library.writeNode(s)) > 0);
                }
            });
        }
        if (NodeCompat.equals(AbstractSchemaInhCommand.TYPE_NONE, fromType)) {
            var wrapperSchema = this.createSchema(schema, fromType);
            wrapperSchema.type = "object";
            this.moveProperties(schema, wrapperSchema);
            /* add */ (schemas.push(wrapperSchema) > 0);
        }
        if (!(schemas.length == 0)) {
            this.copySchemasTo(schemas, schema, toType);
        }
    };
    /**
     * Copies the given list of schemas to the appropriate property on the model
     * @param {OasSchema[]} schemas
     * @param {OasSchema} targetSchema
     * @param {string} inheritanceType
     * @private
     */
    /*private*/ ChangeSchemaInheritanceCommand.prototype.copySchemasTo = function (schemas, targetSchema, inheritanceType) {
        var jsSchemas = ([]);
        schemas.forEach((function (jsSchemas) {
            return function (schema) {
                /* add */ (jsSchemas.push(Library.writeNode(schema)) > 0);
            };
        })(jsSchemas));
        this.copySchemaJsTo(jsSchemas, targetSchema, inheritanceType);
    };
    /**
     * Moves properties from one schema to another.
     * @param {OasSchema} from
     * @param {OasSchema} to
     * @private
     */
    /*private*/ ChangeSchemaInheritanceCommand.prototype.moveProperties = function (from, to) {
        to.properties = from.properties;
        from.properties = null;
        /* values */ (function (obj) { return Object.keys(obj).map(function (key) { return obj[key]; }); })(to.properties).forEach(function (pschema) {
            pschema._parent = to;
        });
        to.required = from.required;
        from.required = null;
    };
    return ChangeSchemaInheritanceCommand;
}(AbstractSchemaInhCommand));
export { ChangeSchemaInheritanceCommand };
ChangeSchemaInheritanceCommand["__class"] = "io.apicurio.datamodels.cmd.commands.ChangeSchemaInheritanceCommand";
ChangeSchemaInheritanceCommand["__interfaces"] = ["io.apicurio.datamodels.cmd.ICommand"];
//# sourceMappingURL=ChangeSchemaInheritanceCommand.js.map