import { AdaptablePredicate } from '../AdaptableState/Common/AdaptablePredicate';
import { AdaptableModule, AdaptableQLModule } from '../AdaptableState/Common/Types';
import { BaseContext } from '../AdaptableState/Common/BaseContext';
import { AdaptableColumn } from '../AdaptableState/Common/AdaptableColumn';
import { AdaptableObject, AggregatedBooleanFunctionName, AggregatedExpressionFunction, AggregatedScalarFunctionName, BooleanFunctionName, ExpressionFunction, ObservableFunctionName, ScalarFunctionName, AdaptableField, AdaptableColumnContext } from '../types';
/**
 * Options for managing Expressions in AdapTable's Query Language
 */
export interface ExpressionOptions<TData = any> {
    /**
     * Whether a Module (or specific expression) should be evaluated by AdapTableQL
     * @defaultValue All Modules are evaluated by AdapTable
     */
    evaluateAdaptableQLExternally?: (context: EvaluateExpressionExternallyContext<TData>) => boolean;
    /**
     * System Boolean Expression Functions available in AdapTableQL
     *
     * @defaultValue null (sets all)
     */
    systemBooleanFunctions?: BooleanFunctionName[] | ((context: GlobalExpressionFunctionsContext<BooleanFunctionName>) => BooleanFunctionName[]);
    /**
     * Custom Boolean Expression Functions available in AdapTableQL
     *
     * @defaultValue null (none)
     */
    customBooleanFunctions?: Record<string, ExpressionFunction> | ((context: GlobalExpressionFunctionsContext<BooleanFunctionName>) => Record<string, ExpressionFunction>);
    /**
     * System Scalar Expression Functions available in AdapTableQL
     *
     * @defaultValue null (sets all)
     */
    systemScalarFunctions?: ScalarFunctionName[] | ((context: GlobalExpressionFunctionsContext<ScalarFunctionName>) => ScalarFunctionName[]);
    /**
     * Custom Scalar Expression Functions available in AdapTableQL
     *
     * @defaultValue null (none)
     */
    customScalarFunctions?: Record<string, ExpressionFunction> | ((context: GlobalExpressionFunctionsContext<ScalarFunctionName>) => Record<string, ExpressionFunction>);
    /**
     * System Observable Expression Functions available in AdapTableQL
     *
     * @defaultValue null (sets all)
     */
    systemObservableFunctions?: ObservableFunctionName[] | ((context: GlobalExpressionFunctionsContext<ObservableFunctionName>) => ObservableFunctionName[]);
    /**
     * System AggregatedBoolean Expression Functions available in AdapTableQL
     *
     * @defaultValue null (sets all)
     */
    systemAggregatedBooleanFunctions?: AggregatedBooleanFunctionName[] | ((context: GlobalExpressionFunctionsContext<AggregatedBooleanFunctionName>) => AggregatedBooleanFunctionName[]);
    /**
     * System AggregatedScalar Expression Functions available in AdapTableQL
     *
     * @defaultValue undefined (sets all)
     */
    systemAggregatedScalarFunctions?: AggregatedScalarFunctionName[] | ((context: GlobalExpressionFunctionsContext<AggregatedScalarFunctionName>) => AggregatedScalarFunctionName[]);
    /**
     * Bespoke Aggregated functions - to complement those provided by AdapTable
     */
    customAggregatedFunctions?: Record<string, AggregatedExpressionFunction> | ((context: GlobalExpressionFunctionsContext<string>) => Record<string, AggregatedExpressionFunction>);
    /**
     * Module-specific Expression Functions available
     *
     * @defaultValue undefined (defaults to available System & Custom values)
     */
    moduleExpressionFunctions?: ModuleExpressionFunctionsMap | ((context: ModuleExpressionFunctionsContext) => ModuleExpressionFunctions | undefined);
    /**
     * Can a given column be included in Expressions
     */
    isColumnQueryable?: (queryableColumnContext: QueryableColumnContext) => boolean;
    /**
     * Validate Expressions before they can be run or saved
     *
     * @defaultValue true
     */
    performExpressionValidation?: boolean;
    /**
     * Maximum time (in milliseconds) to hold a Data Change event in a trailing timeframe
     *
     * @defaultValue 28800000 (~8 hours)
     */
    maxTimeframeSize?: number;
    /**
     * Values to be attached to variables so that a single value can easily be expressed multiple times within a query, or quickly changed to affect the results of a query; evaluated synchronously with each expression evaluation
     */
    customQueryVariables?: Record<string, string | number | boolean | Date | ((context: CustomQueryVariableContext) => string | number | boolean | Date)>;
    /**
     * Reference a Column's Header (i.e. FriendlyName) in all Expression overviews (instead of ColumnId)
     *
     * @defaultValue true
     * @noCodeItem
     */
    displayColumnFriendlyNamesForExpressions?: boolean;
    /**
     * Perform case-sensitive text comparisons when evaluating Expressions
     *
     * @defaultValue false
     * @noCodeItem
     */
    caseSensitiveExpressions?: boolean;
    /**
     * Fields are items in Data Source that are NOT columns but can be used in Expressions (via FIELD keyword)
     */
    fields?: AdaptableField[] | ((context: AdaptableFieldContext) => AdaptableField[]);
}
/**
 * Context passed when evaluating `expressionOptions.evaluateExpressionExternally()`
 */
export interface EvaluateExpressionExternallyContext<TData = any> extends BaseContext {
    /**
     * Module being evaluated: Alert, CalculatedColumn, ColumnFilter, GridFilter
     */
    module: AdaptableQLModule;
    /**
     * AdapTable Object which contains the Expression or Predicates
     */
    object?: AdaptableObject;
    /**
     * Expression to evaluate
     */
    expression?: string;
    /**
     * Any Predicates to evaluate
     */
    predicates?: AdaptablePredicate[];
    /**
     * Columns contained in Expression
     */
    referencedColumns?: AdaptableColumn<TData>[];
}
/**
 * Module specific Expression Functions
 */
export type ModuleExpressionFunctionsMap = Partial<Record<AdaptableModule, ModuleExpressionFunctions>>;
/**
 * Type specific Expression Functions
 */
export interface ModuleExpressionFunctions {
    /**
     * System Boolean Expression Functions available in AdapTableQL
     *
     * @defaultValue null (sets all)
     */
    systemBooleanFunctions?: BooleanFunctionName[] | ((context: GlobalExpressionFunctionsContext<BooleanFunctionName>) => BooleanFunctionName[]);
    /**
     * Custom Boolean Expression Functions available in AdapTableQL
     *
     * @defaultValue null (none)
     */
    customBooleanFunctions?: Record<string, ExpressionFunction> | ((context: GlobalExpressionFunctionsContext<BooleanFunctionName>) => Record<string, ExpressionFunction>);
    /**
     * System Scalar Expression Functions available in AdapTableQL
     *
     * @defaultValue null (sets all)
     */
    systemScalarFunctions?: ScalarFunctionName[] | ((context: GlobalExpressionFunctionsContext<ScalarFunctionName>) => ScalarFunctionName[]);
    /**
     * Custom Scalar Expression Functions available in AdapTableQL
     *
     * @defaultValue null (none)
     */
    customScalarFunctions?: Record<string, ExpressionFunction> | ((context: GlobalExpressionFunctionsContext<ScalarFunctionName>) => Record<string, ExpressionFunction>);
    /**
     * System Observable Expression Functions available in AdapTableQL
     *
     * @defaultValue null (sets all)
     */
    systemObservableFunctions?: ObservableFunctionName[] | ((context: GlobalExpressionFunctionsContext<ObservableFunctionName>) => ObservableFunctionName[]);
    /**
     * System AggregatedBoolean Expression Functions available in AdapTableQL
     *
     * @defaultValue null (sets all)
     */
    systemAggregatedBooleanFunctions?: AggregatedBooleanFunctionName[] | ((context: GlobalExpressionFunctionsContext<AggregatedBooleanFunctionName>) => AggregatedBooleanFunctionName[]);
    /**
     * System AggregatedScalar Expression Functions available in AdapTableQL
     *
     * @defaultValue null (sets all)
     */
    systemAggregatedScalarFunctions?: AggregatedScalarFunctionName[] | ((context: GlobalExpressionFunctionsContext<AggregatedScalarFunctionName>) => AggregatedScalarFunctionName[]);
}
/**
 * Context used when providing Fields programatically
 */
export interface AdaptableFieldContext extends BaseContext {
}
/**
 * Context provided to global expression functions properties property callback
 */
export interface GlobalExpressionFunctionsContext<T> extends BaseContext {
    /**
     * The names of all expression functions available in this context
     */
    availableExpressionFunctionNames: T[];
}
/**
 * Context provided to moduleExpressionFunctions property callback
 */
export interface ModuleExpressionFunctionsContext extends BaseContext {
    /**
     * The Adaptable Module requesting the expression functions
     */
    module: AdaptableModule;
    /**
     * The global boolean expression functions
     */
    availableBooleanFunctionNames: BooleanFunctionName[];
    /**
     * The global scalar expression functions
     */
    availableScalarFunctionNames: ScalarFunctionName[];
    /**
     * The global observable expression functions
     */
    availableObservableFunctionNames: ObservableFunctionName[];
    /**
     * The global aggregated boolean expression functions
     */
    availableAggregatedBooleanFunctionNames: AggregatedBooleanFunctionName[];
    /**
     * The global aggregated scalar expression functions
     */
    availableAggregatedScalarFunctionNames: AggregatedScalarFunctionName[];
}
/**
 * Context passed when evaluating customQueryVariables
 */
export interface CustomQueryVariableContext extends BaseContext {
    /**
     * Optional variable arguments
     */
    args?: any[];
}
/**
 * Context passed when evaluating Queryable Columns
 */
export interface QueryableColumnContext extends AdaptableColumnContext {
}
