/**
 * Contains convenience methods for getting Arcade expressions defined on a layer.
 *
 * @since 4.25
 */
import type CSVLayer from "../CSVLayer.js";
import type FeatureLayer from "../FeatureLayer.js";
import type GeoJSONLayer from "../GeoJSONLayer.js";
import type ImageryLayer from "../ImageryLayer.js";
import type ImageryTileLayer from "../ImageryTileLayer.js";
import type OGCFeatureLayer from "../OGCFeatureLayer.js";
import type OrientedImageryLayer from "../OrientedImageryLayer.js";
import type SceneLayer from "../SceneLayer.js";
import type StreamLayer from "../StreamLayer.js";
import type VoxelLayer from "../VoxelLayer.js";
import type WFSLayer from "../WFSLayer.js";
import type CatalogFootprintLayer from "../catalog/CatalogFootprintLayer.js";
import type KnowledgeGraphSublayer from "../knowledgeGraph/KnowledgeGraphSublayer.js";
import type Sublayer from "./Sublayer.js";
import type { ProfileName } from "../../arcade.js";

/**
 * Returns all Arcade expressions defined on a given layer and provides metadata describing the context for which each expression was authored.
 *
 *
 * > [!WARNING]
 * >
 * > **Known Limitations**
 * >
 * > Expressions set in the following places will not be returned from this method.
 * >
 * > - [DictionaryRenderer](https://developers.arcgis.com/javascript/latest/references/core/renderers/DictionaryRenderer/)
 * > - [CIMSymbol](https://developers.arcgis.com/javascript/latest/references/core/symbols/CIMSymbol/)
 *
 * @param layer - The layer from which to get all Arcade expressions.
 * @returns Resolves to an array of objects containing all the Arcade
 *   expressions defined on the input layer along with metadata describing the context in which each expression was defined.
 */
export function getExpressionsFromLayer(layer: LayerWithExpression): ExpressionInfo[];

/**
 * Represents the result of the [getExpressionsFromLayer()](https://developers.arcgis.com/javascript/latest/references/core/layers/support/arcadeUtils/#getExpressionsFromLayer) method. Contains
 * an Arcade expression, along with metadata about the context in which the expression was defined.
 */
export interface ExpressionInfo {
  /** An Arcade expression defined on a layer. */
  expression: string;
  /** The name of the expression used when referencing it in popup and form templates. */
  name?: string | null;
  /** The expression's title, describing it in the legend and other UI elements. */
  title?: string | null;
  /** Information about the profile, or environment, where the expression was defined. */
  profileInfo: ProfileInfo;
}

export interface ProfileInfo {
  /**
   * Indicates
   *   which [profile](https://developers.arcgis.com/arcade/profiles/) is used to execute the expression.
   */
  name: ProfileName;
  /**
   * Describes the
   *   context (i.e. the API class) where the expression was defined.
   */
  context: ProfileContext;
  /**
   * Indicates the data source used to hydrate
   *   the expression's profile variables.
   */
  source?: "layer" | "feature-reduction";
  /**
   * The return
   *   type of the expression. This is typically set in popup expressions for formatting purposes.
   */
  returnType?: ProfileReturnType;
}

export type ProfileReturnType = "boolean" | "date" | "number" | "string" | "dictionary";

export type LayerWithExpression = CatalogFootprintLayer | CSVLayer | FeatureLayer | GeoJSONLayer | ImageryLayer | ImageryTileLayer | KnowledgeGraphSublayer | OGCFeatureLayer | OrientedImageryLayer | SceneLayer | StreamLayer | Sublayer | VoxelLayer | WFSLayer;

/** Describes the context for which an Arcade expression was defined. */
export type ProfileContext = VisualizationProfileContext | PopupProfileContext | FeatureZProfileContext | "label-class" | "form-template" | "aggregate-field";

/** Describes the context for which an Arcade expression was defined using the visualization profile. */
export type VisualizationProfileContext = "unique-value-renderer" | "class-breaks-renderer" | "dot-density-renderer" | "heatmap-renderer" | "pie-chart-renderer" | "color-variable" | "size-variable" | "opacity-variable" | "rotation-variable";

/** Describes the context for which an Arcade expression was defined using the popup or popup element profile. */
export type PopupProfileContext = "popup-template" | "popup-expression-content";

/** Describes the context for which an Arcade expression was defined using the Feature Z profile. */
export type FeatureZProfileContext = "order-by" | "elevation-info";