/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { OptionDataValue, DimensionLoose, Dictionary } from './types';
import {
    keys, isArray, map, isObject, isString, HashMap, isRegExp, isArrayLike, hasOwn
} from 'zrender/src/core/util';
import { throwError, makePrintable } from './log';
import {
    RawValueParserType, getRawValueParser,
    RelationalOperator, FilterComparator, createFilterComparator
} from '../data/helper/dataValueHelper';


// PENDING:
// (1) Support more parser like: `parser: 'trim'`, `parser: 'lowerCase'`, `parser: 'year'`, `parser: 'dayOfWeek'`?
// (2) Support piped parser ?
// (3) Support callback parser or callback condition?
// (4) At present do not support string expression yet but only stuctured expression.


/**
 * The structured expression considered:
 * (1) Literal simplicity
 * (2) Sementic displayed clearly
 *
 * Sementic supports:
 * (1) relational expression
 * (2) logical expression
 *
 * For example:
 * ```js
 * {
 *     and: [{
 *         or: [{
 *             dimension: 'Year', gt: 2012, lt: 2019
 *         }, {
 *             dimension: 'Year', '>': 2002, '<=': 2009
 *         }]
 *     }, {
 *         dimension: 'Product', eq: 'Tofu'
 *     }]
 * }
 *
 * { dimension: 'Product', eq: 'Tofu' }
 *
 * {
 *     or: [
 *         { dimension: 'Product', value: 'Tofu' },
 *         { dimension: 'Product', value: 'Biscuit' }
 *     ]
 * }
 *
 * {
 *     and: [true]
 * }
 * ```
 *
 * [PARSER]
 * In an relation expression object, we can specify some built-in parsers:
 * ```js
 * // Trim if string
 * {
 *     parser: 'trim',
 *     eq: 'Flowers'
 * }
 * // Parse as time and enable arithmetic relation comparison.
 * {
 *     parser: 'time',
 *     lt: '2012-12-12'
 * }
 * // Normalize number-like string and make '-' to Null.
 * {
 *     parser: 'time',
 *     lt: '2012-12-12'
 * }
 * // Normalize to number:
 * // + number-like string (like '  123  ') can be converted to a number.
 * // + where null/undefined or other string will be converted to NaN.
 * {
 *     parser: 'number',
 *     eq: 2011
 * }
 * // RegExp, include the feature in SQL: `like '%xxx%'`.
 * {
 *     reg: /^asdf$/
 * }
 * {
 *     reg: '^asdf$' // Serializable reg exp, will be `new RegExp(...)`
 * }
 * ```
 *
 *
 * [EMPTY_RULE]
 * (1) If a relational expression set value as `null`/`undefined` like:
 * `{ dimension: 'Product', lt: undefined }`,
 * The result will be `false` rather than `true`.
 * Consider the case like "filter condition", return all result when null/undefined
 * is probably not expected and even dangours.
 * (2) If a relational expression has no operator like:
 * `{ dimension: 'Product' }`,
 * An error will be thrown. Because it is probably a mistake.
 * (3) If a logical expression has no children like
 * `{ and: undefined }` or `{ and: [] }`,
 * An error will be thrown. Because it is probably an mistake.
 * (4) If intending have a condition that always `true` or always `false`,
 * Use `true` or `flase`.
 * The entire condition can be `true`/`false`,
 * or also can be `{ and: [true] }`, `{ or: [false] }`
 */


// --------------------------------------------------
// --- Relational Expression --------------------------
// --------------------------------------------------

/**
 * Date string and ordinal string can be accepted.
 */
interface RelationalExpressionOptionByOp extends Record<RelationalOperator, OptionDataValue> {
    reg?: RegExp | string; // RegExp
};
const RELATIONAL_EXPRESSION_OP_ALIAS_MAP = {
    value: 'eq',

    // PENDING: not good for literal semantic?
    '<': 'lt',
    '<=': 'lte',
    '>': 'gt',
    '>=': 'gte',
    '=': 'eq',
    '!=': 'ne',
    '<>': 'ne'

    // Might mileading for sake of the different between '==' and '===',
    // So dont support them.
    // '==': 'eq',
    // '===': 'seq',
    // '!==': 'sne'

    // PENDING: Whether support some common alias "ge", "le", "neq"?
    // ge: 'gte',
    // le: 'lte',
    // neq: 'ne',
} as const;
type RelationalExpressionOptionByOpAlias = Record<keyof typeof RELATIONAL_EXPRESSION_OP_ALIAS_MAP, OptionDataValue>;

interface RelationalExpressionOption extends
        RelationalExpressionOptionByOp, RelationalExpressionOptionByOpAlias {
    dimension?: DimensionLoose;
    parser?: RawValueParserType;
}

type RelationalExpressionOpEvaluate = (tarVal: unknown, condVal: unknown) => boolean;


class RegExpEvaluator implements FilterComparator {
    private _condVal: RegExp;

    constructor(rVal: unknown) {
        // Support condVal: RegExp | string
        const condValue = this._condVal = isString(rVal) ? new RegExp(rVal)
            : isRegExp(rVal) ? rVal as RegExp
            : null;
        if (condValue == null) {
            let errMsg = '';
            if (__DEV__) {
                errMsg = makePrintable('Illegal regexp', rVal, 'in');
            }
            throwError(errMsg);
        }
    }

    evaluate(lVal: unknown): boolean {
        const type = typeof lVal;
        return type === 'string' ? this._condVal.test(lVal as string)
            : type === 'number' ? this._condVal.test(lVal + '')
            : false;
    }
}




// --------------------------------------------------
// --- Logical Expression ---------------------------
// --------------------------------------------------


interface LogicalExpressionOption {
    and?: LogicalExpressionSubOption[];
    or?: LogicalExpressionSubOption[];
    not?: LogicalExpressionSubOption;
}
type LogicalExpressionSubOption =
    LogicalExpressionOption | RelationalExpressionOption | TrueFalseExpressionOption;



// -----------------------------------------------------
// --- Conditional Expression --------------------------
// -----------------------------------------------------


export type TrueExpressionOption = true;
export type FalseExpressionOption = false;
export type TrueFalseExpressionOption = TrueExpressionOption | FalseExpressionOption;

export type ConditionalExpressionOption =
    LogicalExpressionOption
    | RelationalExpressionOption
    | TrueFalseExpressionOption;

type ValueGetterParam = Dictionary<unknown>;
export interface ConditionalExpressionValueGetterParamGetter<VGP extends ValueGetterParam = ValueGetterParam> {
    (relExpOption: RelationalExpressionOption): VGP
}
export interface ConditionalExpressionValueGetter<VGP extends ValueGetterParam = ValueGetterParam> {
    (param: VGP): OptionDataValue
}

interface ParsedConditionInternal {
    evaluate(): boolean;
}
class ConstConditionInternal implements ParsedConditionInternal {
    value: boolean;
    evaluate(): boolean {
        return this.value;
    }
}
class AndConditionInternal implements ParsedConditionInternal {
    children: ParsedConditionInternal[];
    evaluate() {
        const children = this.children;
        for (let i = 0; i < children.length; i++) {
            if (!children[i].evaluate()) {
                return false;
            }
        }
        return true;
    }
}
class OrConditionInternal implements ParsedConditionInternal {
    children: ParsedConditionInternal[];
    evaluate() {
        const children = this.children;
        for (let i = 0; i < children.length; i++) {
            if (children[i].evaluate()) {
                return true;
            }
        }
        return false;
    }
}
class NotConditionInternal implements ParsedConditionInternal {
    child: ParsedConditionInternal;
    evaluate() {
        return !this.child.evaluate();
    }
}
class RelationalConditionInternal implements ParsedConditionInternal {
    valueGetterParam: ValueGetterParam;
    valueParser: ReturnType<typeof getRawValueParser>;
    // If no parser, be null/undefined.
    getValue: ConditionalExpressionValueGetter;
    subCondList: FilterComparator[];

    evaluate() {
        const needParse = !!this.valueParser;
        // Call getValue with no `this`.
        const getValue = this.getValue;
        const tarValRaw = getValue(this.valueGetterParam);
        const tarValParsed = needParse ? this.valueParser(tarValRaw) : null;

        // Relational cond follow "and" logic internally.
        for (let i = 0; i < this.subCondList.length; i++) {
            if (!this.subCondList[i].evaluate(needParse ? tarValParsed : tarValRaw)) {
                return false;
            }
        }
        return true;
    }
}

function parseOption(
    exprOption: ConditionalExpressionOption,
    getters: ConditionalGetters
): ParsedConditionInternal {
    if (exprOption === true || exprOption === false) {
        const cond = new ConstConditionInternal();
        cond.value = exprOption as boolean;
        return cond;
    }

    let errMsg = '';
    if (!isObjectNotArray(exprOption)) {
        if (__DEV__) {
            errMsg = makePrintable(
                'Illegal config. Expect a plain object but actually', exprOption
            );
        }
        throwError(errMsg);
    }

    if ((exprOption as LogicalExpressionOption).and) {
        return parseAndOrOption('and', exprOption as LogicalExpressionOption, getters);
    }
    else if ((exprOption as LogicalExpressionOption).or) {
        return parseAndOrOption('or', exprOption as LogicalExpressionOption, getters);
    }
    else if ((exprOption as LogicalExpressionOption).not) {
        return parseNotOption(exprOption as LogicalExpressionOption, getters);
    }

    return parseRelationalOption(exprOption as RelationalExpressionOption, getters);
}

function parseAndOrOption(
    op: 'and' | 'or',
    exprOption: LogicalExpressionOption,
    getters: ConditionalGetters
): ParsedConditionInternal {
    const subOptionArr = exprOption[op] as ConditionalExpressionOption[];
    let errMsg = '';
    if (__DEV__) {
        errMsg = makePrintable(
            '"and"/"or" condition should only be `' + op + ': [...]` and must not be empty array.',
            'Illegal condition:', exprOption
        );
    }
    if (!isArray(subOptionArr)) {
        throwError(errMsg);
    }
    if (!(subOptionArr as []).length) {
        throwError(errMsg);
    }
    const cond = op === 'and' ? new AndConditionInternal() : new OrConditionInternal();
    cond.children = map(subOptionArr, subOption => parseOption(subOption, getters));
    if (!cond.children.length) {
        throwError(errMsg);
    }
    return cond;
}

function parseNotOption(
    exprOption: LogicalExpressionOption,
    getters: ConditionalGetters
): ParsedConditionInternal {
    const subOption = exprOption.not as ConditionalExpressionOption;
    let errMsg = '';
    if (__DEV__) {
        errMsg = makePrintable(
            '"not" condition should only be `not: {}`.',
            'Illegal condition:', exprOption
        );
    }
    if (!isObjectNotArray(subOption)) {
        throwError(errMsg);
    }
    const cond = new NotConditionInternal();
    cond.child = parseOption(subOption, getters);
    if (!cond.child) {
        throwError(errMsg);
    }
    return cond;
}

function parseRelationalOption(
    exprOption: RelationalExpressionOption,
    getters: ConditionalGetters
): ParsedConditionInternal {
    let errMsg = '';

    const valueGetterParam = getters.prepareGetValue(exprOption);

    const subCondList = [] as RelationalConditionInternal['subCondList'];
    const exprKeys = keys(exprOption);

    const parserName = exprOption.parser;
    const valueParser = parserName ? getRawValueParser(parserName) : null;

    for (let i = 0; i < exprKeys.length; i++) {
        const keyRaw = exprKeys[i];
        if (keyRaw === 'parser' || getters.valueGetterAttrMap.get(keyRaw)) {
            continue;
        }

        const op: keyof RelationalExpressionOptionByOp = hasOwn(RELATIONAL_EXPRESSION_OP_ALIAS_MAP, keyRaw)
            ? RELATIONAL_EXPRESSION_OP_ALIAS_MAP[keyRaw as keyof RelationalExpressionOptionByOpAlias]
            : (keyRaw as keyof RelationalExpressionOptionByOp);
        const condValueRaw = exprOption[keyRaw];
        const condValueParsed = valueParser ? valueParser(condValueRaw) : condValueRaw;
        const evaluator = createFilterComparator(op, condValueParsed)
            || (op === 'reg' && new RegExpEvaluator(condValueParsed));

        if (!evaluator) {
            if (__DEV__) {
                errMsg = makePrintable(
                    'Illegal relational operation: "' + keyRaw + '" in condition:', exprOption
                );
            }
            throwError(errMsg);
        }

        subCondList.push(evaluator);
    }

    if (!subCondList.length) {
        if (__DEV__) {
            errMsg = makePrintable(
                'Relational condition must have at least one operator.',
                'Illegal condition:', exprOption
            );
        }
        // No relational operator always disabled in case of dangers result.
        throwError(errMsg);
    }

    const cond = new RelationalConditionInternal();
    cond.valueGetterParam = valueGetterParam;
    cond.valueParser = valueParser;
    cond.getValue = getters.getValue;
    cond.subCondList = subCondList;

    return cond;
}

function isObjectNotArray(val: unknown): boolean {
    return isObject(val) && !isArrayLike(val);
}


class ConditionalExpressionParsed {

    private _cond: ParsedConditionInternal;

    constructor(
        exprOption: ConditionalExpressionOption,
        getters: ConditionalGetters
    ) {
        this._cond = parseOption(exprOption, getters);
    }

    evaluate(): boolean {
        return this._cond.evaluate();
    }
};

interface ConditionalGetters<VGP extends ValueGetterParam = ValueGetterParam> {
    prepareGetValue: ConditionalExpressionValueGetterParamGetter<VGP>;
    getValue: ConditionalExpressionValueGetter<VGP>;
    valueGetterAttrMap: HashMap<boolean, string>;
}

export function parseConditionalExpression<VGP extends ValueGetterParam = ValueGetterParam>(
    exprOption: ConditionalExpressionOption,
    getters: ConditionalGetters<VGP>
): ConditionalExpressionParsed {
    return new ConditionalExpressionParsed(exprOption, getters);
}

