<commit_before>/**
 * @license
 * Copyright 2018 JBoss Inc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import {
    ChangeDetectionStrategy,
    ChangeDetectorRef,
    Component,
    EventEmitter,
    Input,
    Output,
    ViewEncapsulation
} from "@angular/core";
import {SimplifiedType} from "oai-ts-commands";
import {Oas20SchemaDefinition, Oas30SchemaDefinition, OasDocument, OasNode, OasVisitorUtil} from "oai-ts-core";
import {DropDownOption} from "../../../../../../../components/common/drop-down.component";
import {FindSchemaDefinitionsVisitor} from "../../../_visitors/schema-definitions.visitor";
import {AbstractBaseComponent} from "../../common/base-component";
import {DocumentService} from "../../../_services/document.service";
import {CommandService} from "../../../_services/command.service";
import {SelectionService} from "../../../_services/selection.service";
import {ObjectUtils} from "apicurio-ts-core";


@Component({
    moduleId: module.id,
    selector: "schema-type-editor",
    templateUrl: "schema-type-editor.component.html",
    styleUrls: [ "schema-type-editor.component.css" ],
    encapsulation: ViewEncapsulation.None,
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class SchemaTypeEditorComponent extends AbstractBaseComponent {
    
    @Input() document: OasDocument;
    @Input() value: SimplifiedType;
    @Input() typeLabel: string = "Type";
    @Input() validationModel: OasNode;
    @Input() validationProperty: string;
    @Input() isParameter: boolean = false;
    @Output() onChange: EventEmitter<SimplifiedType> = new EventEmitter<SimplifiedType>();

    constructor(private changeDetectorRef: ChangeDetectorRef, private documentService: DocumentService,
                private commandService: CommandService, private selectionService: SelectionService) {
        super(changeDetectorRef, documentService, selectionService);
    }

    public hasValidationModel(): boolean {
        return this.validationModel !== null && this.validationModel !== undefined;
    }

    public type(): string {
        if (!ObjectUtils.isNullOrUndefined(this.value)) {
            if (this.value.isEnum()) {
                return "enum";
            }
            return ObjectUtils.undefinedAsNull(this.value.type);
        }
        return null;
    }

    public typeOptions(): DropDownOption[] {
        let options: DropDownOption[] = [
            { value: "array", name: "Array" },
            { value: "enum", name: "Enum" },
            { divider: true },
            { value: "string", name: "String" },
            { value: "integer", name: "Integer" },
            { value: "boolean", name: "Boolean" },
            { value: "number", name: "Number" }
        ];

        if (!this.isParameter) {
            let refPrefix: string = "#/components/schemas/";
            if (this.document.is2xDocument()) {
                refPrefix = "#/definitions/";
            }

            let viz: FindSchemaDefinitionsVisitor = new FindSchemaDefinitionsVisitor(null);
            OasVisitorUtil.visitTree(this.document, viz);
            let defs: (Oas20SchemaDefinition | Oas30SchemaDefinition)[] = viz.getSortedSchemaDefinitions();
            if (defs.length > 0) {
                options.push({divider: true});
                defs.forEach(def => {
                    let defName: string = (def.ownerDocument().is2xDocument()) ? (def as Oas20SchemaDefinition).definitionName() : (def as Oas30SchemaDefinition).name();
                    options.push({
                        value: refPrefix + defName,
                        name: defName
                    });
                });
            }
        }

        return options;
    }

    public typeOf(): string {
        if (this.value && this.value.of) {
            return ObjectUtils.undefinedAsNull(this.value.of.type);
        }
        return null;
    }

    public typeOfOptions(): DropDownOption[] {
        let options: DropDownOption[] = [
            { value: "string", name: "String" },
            { value: "integer", name: "Integer" },
            { value: "boolean", name: "Boolean" },
            { value: "number", name: "Number" }
        ];

        if (!this.isParameter) {
            let refPrefix: string = "#/components/schemas/";
            if (this.document.is2xDocument()) {
                refPrefix = "#/definitions/";
            }

            let viz: FindSchemaDefinitionsVisitor = new FindSchemaDefinitionsVisitor(null);
            OasVisitorUtil.visitTree(this.document, viz);
            let defs: (Oas20SchemaDefinition | Oas30SchemaDefinition)[] = viz.getSortedSchemaDefinitions();
            if (defs.length > 0) {
                options.push({divider: true});
                defs.forEach(def => {
                    let defName: string = (def.ownerDocument().is2xDocument()) ? (def as Oas20SchemaDefinition).definitionName() : (def as Oas30SchemaDefinition).name();
                    options.push({
                        value: refPrefix + defName,
                        name: defName
                    });
                });
            }
        }

        return options;
    }

    public typeAs(): string {
        if (ObjectUtils.isNullOrUndefined(this.value)) {
            return null;
        }
        if (this.value.isArray() && this.value.of && this.value.of.isSimpleType()) {
            return ObjectUtils.undefinedAsNull(this.value.of.as);
        }
        if (this.value.isSimpleType()) {
            return ObjectUtils.undefinedAsNull(this.value.as);
        }
        return null;
    }

    public typeAsOptions(): DropDownOption[] {
        let options: DropDownOption[];
        let st: SimplifiedType = this.value;
        if (this.value && this.value.isArray() && this.value.of && this.value.of.isSimpleType()) {
            st = this.value.of;
        }
        if (st.type === "string") {
            options = [
                { value: null, name: "String" },
                { value: "byte", name: "Byte" },
                { value: "binary", name: "Binary" },
                { value: "date", name: "Date" },
                { value: "date-time", name: "DateTime" },
                { value: "password", name: "Password" }
            ];<commit_msg>Support "file" as an option for OpenAPI 2 form body parameters (#679)<commit_after>/**
 * @license
 * Copyright 2018 JBoss Inc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import {
    ChangeDetectionStrategy,
    ChangeDetectorRef,
    Component,
    EventEmitter,
    Input,
    Output,
    ViewEncapsulation
} from "@angular/core";
import {SimplifiedType} from "oai-ts-commands";
import {Oas20SchemaDefinition, Oas30SchemaDefinition, OasDocument, OasNode, OasVisitorUtil} from "oai-ts-core";
import {DropDownOption} from "../../../../../../../components/common/drop-down.component";
import {FindSchemaDefinitionsVisitor} from "../../../_visitors/schema-definitions.visitor";
import {AbstractBaseComponent} from "../../common/base-component";
import {DocumentService} from "../../../_services/document.service";
import {CommandService} from "../../../_services/command.service";
import {SelectionService} from "../../../_services/selection.service";
import {ObjectUtils} from "apicurio-ts-core";


@Component({
    moduleId: module.id,
    selector: "schema-type-editor",
    templateUrl: "schema-type-editor.component.html",
    styleUrls: [ "schema-type-editor.component.css" ],
    encapsulation: ViewEncapsulation.None,
    changeDetection: ChangeDetectionStrategy.OnPush
})
/**
 * Component to select a "SimplifiedType" value
 */
export class SchemaTypeEditorComponent extends AbstractBaseComponent {

    @Input() document: OasDocument;
    @Input() value: SimplifiedType;
    @Input() typeLabel: string = "Type";
    @Input() validationModel: OasNode;
    @Input() validationProperty: string;

    /**
     * Is the component being used in "data type" definition?
     * i.e. should the dropdown contain references to data type schemas?
     */
    @Input() isParameter: boolean = false;

    /**
     * Emit the value when it is updated
     */
    @Output() onChange: EventEmitter<SimplifiedType> = new EventEmitter<SimplifiedType>();

    constructor(private changeDetectorRef: ChangeDetectorRef, private documentService: DocumentService,
                private commandService: CommandService, private selectionService: SelectionService) {
        super(changeDetectorRef, documentService, selectionService);
    }

    public hasValidationModel(): boolean {
        return this.validationModel !== null && this.validationModel !== undefined;
    }

    public type(): string {
        if (!ObjectUtils.isNullOrUndefined(this.value)) {
            if (this.value.isEnum()) {
                return "enum";
            }
            return ObjectUtils.undefinedAsNull(this.value.type);
        }
        return null;
    }

    /**
     * Main options
     */
    public typeOptions(): DropDownOption[] {
        let options: DropDownOption[] = [
            { value: "array", name: "Array" },
            { value: "enum", name: "Enum" },
            { divider: true },
            { value: "string", name: "String" },
            { value: "integer", name: "Integer" },
            { value: "boolean", name: "Boolean" },
            { value: "number", name: "Number" }
        ];

        /**
         * Add schema definitions to the dropdown menu
         */
        if (!this.isParameter) {
            options = [...options, ...this.getSchemaDefinitionsOptions()]
        } else if(this.document.is2xDocument()) {
            options = [...options, { divider: true }, { value: "file", name: "File" }]
        }

        return options;
    }

    public typeOf(): string {
        if (this.value && this.value.of) {
            return ObjectUtils.undefinedAsNull(this.value.of.type);
        }
        return null;
    }

    /**
     * Additional options when e.g. an array is selected,
     * to choose the type of the array elements
     */
    public typeOfOptions(): DropDownOption[] {
        let options: DropDownOption[] = [
            { value: "string", name: "String" },
            { value: "integer", name: "Integer" },
            { value: "boolean", name: "Boolean" },
            { value: "number", name: "Number" }
        ];

        if (!this.isParameter) {
            options = [...options, ...this.getSchemaDefinitionsOptions()]
        }
        return options;
    }

    /**
     * Get additional options, when reference to "schema definition data type"
     * can be used
     */
    private getSchemaDefinitionsOptions(): DropDownOption[] {
        let options: DropDownOption[] = [];
        let refPrefix: string = "#/components/schemas/";
        if (this.document.is2xDocument()) {
            refPrefix = "#/definitions/";
        }

        let viz: FindSchemaDefinitionsVisitor = new FindSchemaDefinitionsVisitor(null);
        OasVisitorUtil.visitTree(this.document, viz);
        let defs: (Oas20SchemaDefinition | Oas30SchemaDefinition)[] = viz.getSortedSchemaDefinitions();
        if (defs.length > 0) {
            options.push({divider: true});
            defs.forEach(def => {
                let defName: string = (def.ownerDocument().is2xDocument()) ? (def as Oas20SchemaDefinition).definitionName() : (def as Oas30SchemaDefinition).name();
                options.push({
                    value: refPrefix + defName,
                    name: defName
                });
            });
        }
        return options;
    }

    public typeAs(): string {
        if (ObjectUtils.isNullOrUndefined(this.value)) {
            return null;
        }
        if (this.value.isArray() && this.value.of && this.value.of.isSimpleType()) {
            return ObjectUtils.undefinedAsNull(this.value.of.as);
        }
        if (this.value.isSimpleType()) {
            return ObjectUtils.undefinedAsNull(this.value.as);
        }
        if (this.value.isFileType()) {
            return ObjectUtils.undefinedAsNull(this.value);
        }
        return null;
    }

    /**
     * Specify a "sub-type" for some of the selected types,
     * e.g. int64 for an Integer
     */
    public typeAsOptions(): DropDownOption[] {
        let options: DropDownOption[];
        let st: SimplifiedType = this.value;
        if (this.value && this.value.isArray() && this.value.of && this.value.of.isSimpleType()) {
            st = this.value.of;
        }
        if (st.type === "string") {
            options = [
                { value: null, name: "String" },
                { value: "byte", name: "Byte" },
                { value: "binary", name: "Binary" },
                { value: "date", name: "Date" },
                { value: "date-time", name: "DateTime" },
                { value: "password", name: "Password" }
            ];
{'fraction_non_alphanumeric': 0.12997767696406712, 'fraction_numerical': 0.0046086267732411606, 'mean_word_length': 2.263157894736842, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4946065', 'n_tokens_mistral': 3798, 'n_tokens_neox': 3693, 'n_words': 947}