import { AbstractParseTreeVisitor, ParseTree } from "antlr4ts/tree/index.js";
import { WebdaQLLexer } from "./WebdaQLLexer.js";
import { AndLogicExpressionContext, BinaryComparisonExpressionContext, BooleanLiteralContext, ContainsExpressionContext, InExpressionContext, IntegerLiteralContext, LikeExpressionContext, LimitExpressionContext, OffsetExpressionContext, OrLogicExpressionContext, OrderExpressionContext, OrderFieldExpressionContext, SetExpressionContext, StringLiteralContext, WebdaqlContext } from "./WebdaQLParserParser.js";
import { WebdaQLParserVisitor } from "./WebdaQLParserVisitor.js";
type value = boolean | string | number;
/**
 * Meta Query Language
 *
 *
 */
export declare namespace WebdaQL {
    interface OrderBy {
        field: string;
        direction: "ASC" | "DESC";
    }
    function PrependCondition(query?: string, condition?: string): string;
    /**
     * Create Expression based on the parsed token
     *
     * Expression allow to optimize and split between Query and Filter
     */
    class ExpressionBuilder extends AbstractParseTreeVisitor<Query> implements WebdaQLParserVisitor<any> {
        /**
         * Contain the parsed limit
         */
        limit: number;
        /**
         * Contain the parsed offset
         */
        offset: string;
        orderBy: OrderBy[];
        /**
         * Default result for the override
         * @returns
         */
        protected defaultResult(): Query;
        /**
         * Get offset
         * @returns
         */
        getOffset(): string;
        /**
         * Get limit
         * @returns
         */
        getLimit(): number;
        /**
         * Read the limit
         * @param ctx
         */
        visitLimitExpression(ctx: LimitExpressionContext): void;
        /**
         * Read the offset if provided
         * @param ctx
         */
        visitOffsetExpression(ctx: OffsetExpressionContext): void;
        /**
         * Visit a order field expression
         */
        visitOrderFieldExpression(ctx: OrderFieldExpressionContext): OrderBy;
        /**
         * Read the order by values
         */
        visitOrderExpression(ctx: OrderExpressionContext): void;
        /**
         * Return only AndExpression
         * @param ctx
         * @returns
         */
        visitWebdaql(ctx: WebdaqlContext): Query;
        /**
         * Simplify Logic expression and regroup them
         * @param ctx
         * @returns
         */
        getComparison(ctx: AndLogicExpressionContext | OrLogicExpressionContext): any[];
        /**
         * Get the AndExpression, regrouping all the parameters
         *
         * By default the parser is doing a AND (b AND (c AND d)) creating 3 depth expressions
         * This visitor simplify to a AND b AND c AND d with only one Expression
         */
        visitAndLogicExpression(ctx: AndLogicExpressionContext): AndExpression;
        /**
         * Implement the BinaryComparison with all methods managed
         */
        visitBinaryComparisonExpression(ctx: BinaryComparisonExpressionContext): ComparisonExpression<ComparisonOperator>;
        /**
         * Visit each value of the [..., ..., ...] set
         */
        visitSetExpression(ctx: SetExpressionContext): value[];
        /**
         * a LIKE "%A?"
         * @param ctx
         * @returns
         */
        visitLikeExpression(ctx: LikeExpressionContext): ComparisonExpression<"LIKE">;
        /**
         * Map the a IN ['b','c']
         */
        visitInExpression(ctx: InExpressionContext): ComparisonExpression<"IN">;
        /**
         * Map the a CONTAINS 'b'
         */
        visitContainsExpression(ctx: ContainsExpressionContext): ComparisonExpression<"CONTAINS">;
        /**
         * Get the OrExpression, regrouping all the parameters
         *
         * By default the parser is doing a OR (b OR (c OR d)) creating 3 depth expressions
         * This visitor simplify to a OR b OR c OR d with only one Expression
         */
        visitOrLogicExpression(ctx: OrLogicExpressionContext): OrExpression;
        /**
         * Read the string literal (removing the simple or double bracket)
         */
        visitStringLiteral(ctx: StringLiteralContext): string;
        /**
         * Read the boolean literal
         */
        visitBooleanLiteral(ctx: BooleanLiteralContext): boolean;
        /**
         * Read the number literal
         */
        visitIntegerLiteral(ctx: IntegerLiteralContext): number;
    }
    /**
     * Represent a full Query
     */
    interface Query {
        /**
         * Filtering part of the expression
         */
        filter: Expression;
        /**
         * Limit value
         */
        limit?: number;
        /**
         * Offset value
         */
        continuationToken?: string;
        /**
         * Order by clause
         */
        orderBy?: OrderBy[];
        /**
         * Get the string representation of the query
         */
        toString(): string;
    }
    /**
     * Represent the query expression or subset
     */
    abstract class Expression<T = string> {
        operator: T;
        constructor(operator: T);
        /**
         * Evaluate the expression for the target object
         * @param target to evaluate
         */
        abstract eval(target: any): boolean;
        /**
         * Return the representation of the expression
         * @param depth
         */
        abstract toString(depth?: number): string;
    }
    type ComparisonOperator = "=" | "<=" | ">=" | "<" | ">" | "!=" | "LIKE" | "IN" | "CONTAINS";
    /**
     * Comparison expression
     */
    class ComparisonExpression<T extends ComparisonOperator = ComparisonOperator> extends Expression<T> {
        /**
         * Right side of the comparison
         */
        value: value | value[];
        /**
         * Attribute to read from the object (split by .)
         */
        attribute: string[];
        /**
         *
         * @param operator of the expression
         * @param attribute of the object to read
         * @param value
         */
        constructor(operator: T, attribute: string, value: value | any[]);
        static likeToRegex(like: string): RegExp;
        /**
         * Read the value from the object
         *
         * @param target
         * @returns
         */
        static getAttributeValue(target: any, attribute: string[]): any;
        /**
         * Set the value of the attribute based on the assignment
         *
         * If used as a Set expression
         * @param target
         */
        setAttributeValue(target: any): void;
        /**
         * @override
         */
        eval(target: any): boolean;
        /**
         * Return a string represantation of a value
         */
        toStringValue(value: value | value[]): string;
        /**
         * Allow subclass to create different display
         */
        toStringAttribute(): string;
        /**
         * Allow subclass to create different display
         */
        toStringOperator(): T;
        /**
         * @override
         */
        toString(): string;
    }
    /**
     * Abstract logic expression (AND|OR)
     *
     * Could add XOR in the future
     */
    abstract class LogicalExpression<T> extends Expression<T> {
        /**
         * Contains the members of the logical expression
         */
        children: Expression[];
        /**
         *
         * @param operator
         * @param children
         */
        constructor(operator: T, children: Expression[]);
        /**
         * @override
         */
        toString(depth?: number): string;
    }
    /**
     * AND Expression implementation
     */
    class AndExpression extends LogicalExpression<"AND"> {
        /**
         * @param children Expressions to use for AND
         */
        constructor(children: Expression[]);
        /**
         * @override
         */
        eval(target: any): boolean;
    }
    /**
     * OR Expression implementation
     */
    class OrExpression extends LogicalExpression<"OR"> {
        /**
         * @param children Expressions to use for OR
         */
        constructor(children: Expression[]);
        /**
         * @override
         */
        eval(target: any): boolean;
    }
    /**
     *
     */
    class QueryValidator {
        protected sql: string;
        protected lexer: WebdaQLLexer;
        protected tree: WebdaqlContext;
        protected query: Query;
        protected builder: ExpressionBuilder;
        constructor(sql: string, builder?: ExpressionBuilder);
        hasCondition(): boolean;
        toString(): string;
        merge(query: string, type?: "OR" | "AND"): this;
        /**
         * Get offset
         * @returns
         */
        getOffset(): string;
        /**
         * Get limit
         * @returns
         */
        getLimit(): number;
        /**
         * Get the expression by itself
         * @returns
         */
        getExpression(): Expression;
        /**
         * Retrieve parsed query
         * @returns
         */
        getQuery(): Query;
        /**
         * Verify if a target fit the expression
         * @param target
         * @returns
         */
        eval(target: any): boolean;
        /**
         * Display parse tree back as query
         * @param tree
         * @returns
         */
        displayTree(tree?: ParseTree): string;
    }
    /**
     * For now reuse same parser
     */
    class SetterValidator extends QueryValidator {
        constructor(sql: string);
        eval(target: any): boolean;
        assign(target: any, expression: Expression): void;
    }
    class PartialValidator extends QueryValidator {
        builder: PartialExpressionBuilder;
        constructor(query: string, builder?: PartialExpressionBuilder);
        /**
         * Eval the query
         * @param target
         * @param partial
         * @returns
         */
        eval(target: any, partial?: boolean): boolean;
        /**
         * Return if the result ignored some fields
         * @returns
         */
        wasPartialMatch(): boolean;
    }
    class PartialComparisonExpression<T extends ComparisonOperator = ComparisonOperator> extends ComparisonExpression<T> {
        protected builder: PartialExpressionBuilder;
        constructor(builder: PartialExpressionBuilder, op: T, attribute: string, value: any);
        /**
         * Override the eval to check if the attribute is present
         * if not and we are in partial mode, return true
         *
         * @param target
         * @returns
         */
        eval(target: any): boolean;
    }
    class PartialExpressionBuilder extends ExpressionBuilder {
        /**
         * Enforce the partial mode
         */
        partial: boolean;
        /**
         * If eval was called in partial mode
         */
        partialMatch: boolean;
        setPartial(partial: boolean): void;
        setPartialMatch(partial: boolean): void;
        /**
         * a LIKE "%A?"
         * @param ctx
         * @returns
         */
        visitLikeExpression(ctx: any): PartialComparisonExpression<"LIKE">;
        /**
         * Implement the BinaryComparison with all methods managed
         */
        visitBinaryComparisonExpression(ctx: any): PartialComparisonExpression<any>;
        /**
         * Map the a IN ['b','c']
         */
        visitInExpression(ctx: any): PartialComparisonExpression<"IN">;
        /**
         * Map the a CONTAINS 'b'
         */
        visitContainsExpression(ctx: any): PartialComparisonExpression<"CONTAINS">;
    }
    /**
     * Remove artifact from sanitize-html inside query
     * @param query
     * @returns
     */
    function unsanitize(query: string): string;
}
export {};
