/*-
 * ~~~~~~licensing~~~~~~
 * test-producers
 * ==========
 * Copyright (C) 2020 - 2025 EmDev LLC
 * ==========
 * You may not use this file except in accordance with the License Terms of the Copyright
 * Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
 * rights to the Software and any copies are the property of the Copyright Holder. Unless
 * it is explicitly allowed the Copyright Holder, the User is prohibited from using the
 * Software for commercial purposes to provide services to third parties.
 * 
 * The Copyright Holder hereby declares that the Software is provided on an "AS IS".
 * Under no circumstances does the Copyright Holder guarantee or promise that the
 * Software provided by him will be suitable or not suitable for the specific purposes
 * of the User, that the Software will meet all commercial and personal subjective
 * expectations of the User, that the Software will work properly, without technical
 * errors, quickly and uninterruptedly.
 * 
 * Under no circumstances shall the Copyright Holder or its Affiliates is not liable
 * to the User for any direct or indirect losses of the User, his expenses or actual
 * damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
 * or damage to data, property, etc.
 * ~~~~~~/licensing~~~~~~
 */
package ru.entaxy.platform.base.objects;

import java.util.List;

public interface EntaxyObject {

    public interface HEADERS {

        String ENTAXY_GENERATED = "Entaxy-Generated";
        String MAIN_OBJECT = "Entaxy-Main-Object";
        String GENERATED_OBJECTS = "Entaxy-Generated-Object";
        // public static final String HEADER_MAIN_OBJECT_ID = "Entaxy-Main-Object-Id";
        // public static final String HEADER_MAIN_OBJECT_TYPE = "Entaxy-Main-Object-Type";
        // public static final String HEADER_MAIN_OBJECT_FACTORY_ID = "Entaxy-Main-Object-Factory";
        // public static final String HEADER_OBJECT_ID = "Entaxy-Generated-Object";
        // public static final String HEADER_OBJECT_TYPE = "Entaxy-Generated-Object-Type";
        String GENERATED_OBJECTS_CONFIG = "Entaxy-Generated-Object-Configuration";

    }

    public interface FIELDS {

        public static final String FACTORY_ID = "factoryId";
        public static final String SCOPE = "scope";

        public static final String OBJECT_ID = "objectId";
        public static final String OBJECT_TYPE = "type";

        public static final String IS_REF = "isRef";
        public static final String IS_BACK_REF = "isBackRef";
        public static final String IS_REF_BY_VALUE_ONLY = "isRefByValueOnly";
        public static final String REF_FIELD = "refField";

        public static final String DEFAULT_VALUE = "defaultValue";

        public static final String PROPERTIES = "properties";

        public static final String FIELDS_TO_PUBLISH = "##publish";
    }

    public interface OBJECT_TYPES {

        public static final String ENTAXY_RUNTIME_TYPE_PREFIX = "entaxy.runtime.";

        public static final String PROFILE = ENTAXY_RUNTIME_TYPE_PREFIX + "profile";
        public static final String CONNECTOR = ENTAXY_RUNTIME_TYPE_PREFIX + "connector";
        public static final String CONNECTION = ENTAXY_RUNTIME_TYPE_PREFIX + "connection";
        public static final String DEFAULT_ROUTE = ENTAXY_RUNTIME_TYPE_PREFIX + "default-route";

        public static boolean isRuntimeType(String typeName) {
            return (typeName != null) && typeName.startsWith(ENTAXY_RUNTIME_TYPE_PREFIX);
        }

    }

    public enum OBJECT_RELATION {
        ASSOCIATION,
        AGGREGATION,
        COMPOSITION,
        DEPENDENCY,
        USE
    }

    public interface OBJECT_SCOPE {

        String PRIVATE = "private";
        String PROTECTED = "protected";
        String PUBLIC = "public";

    }

    public enum OBJECT_RELATION_SCOPE {
        RUNTIME,
        DESIGN
    }

    public interface RelationDescriptor {
        OBJECT_RELATION getType();

        String getName();

        String getGroup();

        OBJECT_RELATION_SCOPE getScope();

        default boolean isSubordinating() {
            return OBJECT_RELATION.AGGREGATION.equals(getType())
                    || OBJECT_RELATION.COMPOSITION.equals(getType());
        }

    }

    public interface Relation extends RelationDescriptor {

        EntaxyObject getSource();

        EntaxyObject getTarget();

        boolean isDefinedInSource();

    }

    public interface CAPABILITIES {
        String ATTR_DISPLAY_NAME = "displayName";
        String ATTR_RELATION = "relation";
        String ATTR_SCOPE = "scope";
        String ATTR_OWNER = "owner";
    }

    public static interface BundleInfo {
        public long getBundleId();
    }

    public String getId();

    public String getType();

    @Deprecated
    public default String getObjectId() {
        return getId();
    };

    @Deprecated
    public default String getObjectType() {
        return getType();
    };

    public default String getObjectFullId() {
        return getId() + ":" + getType();
    };

    public String getDisplayName();

    public String getScope();

    public String getOwner();

    public String getFactoryId();

    public BundleInfo getBundleInfo();

    public String getConfiguration();

    public boolean isProvided();

    public boolean isComplete();

    public boolean isGhost();

    public List<Relation> getRelations();

    public List<Relation> getIncomingRelations();
}
