/** @since 5.0 */
export type OriginName = "defaults" | "service" | "portal-item" | "web-scene" | "web-map" | "link-chart" | "user";

export type ReadableOriginName = "service" | "portal-item" | "web-scene" | "web-map" | "link-chart";

/** @since 5.0 */
export interface Types<T extends Base = any, Base = T> {
  /** @since 5.0 */
  key: string | ((obj: any) => string);
  /** @since 5.0 */
  base: (abstract new (...args: any[]) => Base) | null;
  /** @since 5.0 */
  typeMap: Record<string, new (...params: any[]) => T>;
}

/**
 * Casts a value from one type to another.
 *
 * @param value - the value.
 * @returns the cast value.
 * @since 5.0
 */
export type Caster<T = any> = (value: any) => T;

/** @since 5.0 */
export interface PropertyMetadataBase<T extends Base = any, Base = T> {
  /**
   * The function to use to [autocast](https://developers.arcgis.com/javascript/latest/autocasting/) the property. Alternative to define the `type`. The function is called with the value set by the user and should return the cast value.
   *
   * @since 5.0
   */
  cast?: Caster<T> | null;
  /**
   * The default value for the property.
   *
   * @since 5.0
   */
  value?: T | null;
  /**
   * Property names of dependencies.
   *
   * @deprecated Accessor properties used in getters are automatically tracked and there is no need to specify dependencies manually.
   * @since 5.0
   */
  dependsOn?: string[];
  /**
   * The constructor used to [autocast](https://developers.arcgis.com/javascript/latest/autocasting/) the property.
   *
   * @since 5.0
   */
  type?: any;
  /**
   * Indicates whether the property is read-only.
   *
   * @default false
   * @since 5.0
   */
  readOnly?: boolean;
  /**
   * Indicates whether the property can be set during construction but is otherwise read-only.
   *
   * @default false
   * @since 5.0
   */
  constructOnly?: boolean;
}

/** @since 5.0 */
export interface InputPropertyMetadata<T extends Base = any, Base = T> extends PropertyMetadataBase<T, Base> {
  /**
   * The property decorator that creates a two-way binding between the property it decorates and an inner property of one of its members.
   *
   * @since 5.0
   */
  aliasOf?: string;
}