Source: package/connector/connection_type.js

import { Reporter } from '../../reporter/reporter.js';
import { checkPropTypes, unique } from '../../lib.js';
import { BuildableComponent } from "../component/buildable_component.js";
import { ConnectorType } from "./connector_type.js";
import { Connector } from "./connector.js";
import { Project } from '../../project.js';

/** AllowedConnectionType */
class ConnectionType extends BuildableComponent {

    /**
     * @param {Reporter} reporter
     * @param {Object} settings
     * @param {UUID} [settings.id]
     * @param {string} [settings.name]
     * @param {Array<ConnectorType>} settings.connectorTypes The types of connector that can connect.
     * @param {ConnectorType} [settings.parent] The connection type that is the parent if this is a hierarchical relationship.
     * @param {Array<Connector>} [settings.connectors] A Connection is a Connectable. This settings specifies the connectors for that feature.
     */

    constructor(reporter, settings) {

        if ( ! settings.connectors) {
            settings.connectors = [];
        }

        super(
            reporter,
            settings,
            {
                parse: {
                    connectorTypes: 'integral',
                    connectors: 'integral'
                }
            });

        checkPropTypes(
            settings,
            {
                connectorTypes: val => {
                    if (!Array.isArray(val)) {
                        return 'Not an array';
                    }

                    if ( val.length !== 2) {
                        return `${val.length} connector types specified, but only 2 are allowed.`;
                    }

                    for ( let i = 0 ; i < val.length ; i += 1 ) {
                        const ct = val [ i ];

                        if (! ( ct instanceof ConnectorType)) {
                            return `Entry connectorTypes[${i}] is not a ConnectorType, but a ${ct.constructor.name}`;
                        }
                    }

                    // duplicates are allowed, a connector type can connect to itself

                    // if (val.filter(unique).length !== val.length) {
                    //     return 'Duplicate connectorTypes specified, this is not allowed';
                    // }

                    return true;
                },

                // connectors: val => {
                //     if (!Array.isArray(val)) {
                //         return 'Value is not an array'
                //     }

                //     for (let i = 0; i < val.length; i += 1) {
                //         const ctr = val[i];

                //         if (!(ctr instanceof Connector)) {
                //             return `Entry connectors[${i}] is not a Connector, but a ${ctr.constructor.name}`;
                //         }
                //     }
                // }
            },
            {
                parent: [
                    ConnectorType,
                    val => {
                        if ( ! settings.connectorTypes.includes( val )) {
                            return `Parent connector type is not in allowed connector types.`;
                        }
                        return true;
                    }
                ]
            }
        );
    }

    static _exportName = {
        singular: 'connectionType',
        plural: 'connectionTypes'
    };

    /**
     * True for non-hierarchical (no parent/child) relationships, where both connected parties are equal
     * @type {Boolean}
     */

    get isEqual() {
        return this._settings.parent === undefined ? true : false;
    }


    async _build(part, quality ) {

        switch (part) {

            case 'UI':
                if (this._settings.thumbnail) {
                    this._setContent('UI', quality, this._settings.thumbnail.content.main[quality]);
                }
                else {
                    this._setContent('UI', quality, Project.defaultImages.missing.cloneNode(true));
                }
                break;

            case 'main':
                const content = this._settings;

                // for (let setQuality of Component.qualities) {

                //     this._setContent('main', setQuality, content);

                // }

                this._setContent('main', quality, content);
                break;

            default:

                this._setContent(part, quality, null);
                
                break;
        }

        return this;
    }

}

export { ConnectionType };