declare namespace catalog {
  interface AttributeProps {
    indexKind: AttributeIndexKind;
    autogenerate: boolean;
    unique: boolean;
    primKey: boolean;
    exposed: boolean;
    autosequence: boolean;
    keywordIndexed: boolean;
    not_null: boolean; // TODO: to be renamed to mandatory
    minValue: number;
    maxValue: number;
    simpleDate: boolean;
    defaultValue: any;
    extraProperties: IAttributeProperties;
    styled_text: boolean;
    comment: string;
    events: any[];
  }
  interface BaseAttribute extends Partial<AttributeProps> {
    /**
     * name of the attribute
     */
    name: string;
    /**
     * represents the actual type of the attribute (storage, relatedentity, relatedEntities, alias, calculated);
     */
    kind: AttributeKind;
    /**
     * Scope of the attribute (publicOnServer is equivalent to private)
     */
    scope: Scope;
  }

  interface StorageAttribute extends BaseAttribute {
    kind: 'storage';
    type: AttributeType;
  }

  interface RelatedEntityAttribute extends BaseAttribute {
    kind: 'relatedEntity';
    /**
     * the value for the type property is the name of originating dataclass.
     */
    type: string;
  }

  interface RelatedEntitiesAttribute extends BaseAttribute {
    kind: 'relatedEntities';
    /**
     * the value for the type property is the `selection name` of originating dataclass.
     */
    type: string;
    /**
     * the path to the related attribute in the originating dataclass.
     */
    path: string;
    reversePath?: boolean;
  }

  interface AliasAttribute extends BaseAttribute {
    kind: 'alias';
    /**
     * in the case of alias, the type can be:
     * - storage type. (bool, number, string, ...etc)
     * - the `name` of the dataclass in case `behavior` is set to `relatedEntity`
     * - the `selection name` of the dataclass in case `behavior` is set to `relatedEntities`
     */
    type: string;
    path: string;
    behavior?: 'relatedEntity' | 'relatedEntities';
    reversePath?: string;
  }

  interface CalculatedAttribute extends BaseAttribute {
    kind: 'calculated';
    type: string;
    path?: string;
    behavior?: 'relatedEntity' | 'relatedEntities';
  }

  type Attribute =
    | StorageAttribute
    | RelatedEntityAttribute
    | RelatedEntitiesAttribute
    | AliasAttribute
    | CalculatedAttribute;
}
