// 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 { RecordBatch } from './recordbatch';
import { Vector, DictionaryVector } from './vector';

export type ValueFunc<T> = (idx: number, cols: RecordBatch) => T | null;
export type PredicateFunc = (idx: number, cols: RecordBatch) => boolean;

export abstract class Value<T> {
    eq(other: Value<T> | T): Predicate {
        if (!(other instanceof Value)) { other = new Literal(other); }
        return new Equals(this, other);
    }
    lteq(other: Value<T> | T): Predicate {
        if (!(other instanceof Value)) { other = new Literal(other); }
        return new LTeq(this, other);
    }
    gteq(other: Value<T> | T): Predicate {
        if (!(other instanceof Value)) { other = new Literal(other); }
        return new GTeq(this, other);
    }
}

export class Literal<T= any> extends Value<T> {
    constructor(public v: T) { super(); }
}

export class Col<T= any> extends Value<T> {
    // @ts-ignore
    public vector: Vector;
    // @ts-ignore
    public colidx: number;

    constructor(public name: string) { super(); }
    bind(batch: RecordBatch) {
        if (!this.colidx) {
            // Assume column index doesn't change between calls to bind
            //this.colidx = cols.findIndex(v => v.name.indexOf(this.name) != -1);
            this.colidx = -1;
            const fields = batch.schema.fields;
            for (let idx = -1; ++idx < fields.length;) {
                if (fields[idx].name === this.name) {
                    this.colidx = idx;
                    break;
                }
            }
            if (this.colidx < 0) { throw new Error(`Failed to bind Col "${this.name}"`); }
        }
        this.vector = batch.getChildAt(this.colidx)!;
        return this.vector.get.bind(this.vector);
    }
}

export abstract class Predicate {
    abstract bind(batch: RecordBatch): PredicateFunc;
    and(expr: Predicate): Predicate { return new And(this, expr); }
    or(expr: Predicate): Predicate { return new Or(this, expr); }
    ands(): Predicate[] { return [this]; }
}

export abstract class ComparisonPredicate<T= any> extends Predicate {
    constructor(public readonly left: Value<T>, public readonly right: Value<T>) {
        super();
    }

    bind(batch: RecordBatch) {
        if (this.left instanceof Literal) {
            if (this.right instanceof Literal) {
                return this._bindLitLit(batch, this.left, this.right);
            } else { // right is a Col

                return this._bindLitCol(batch, this.left, this.right as Col);
            }
        } else { // left is a Col
            if (this.right instanceof Literal) {
                return this._bindColLit(batch, this.left as Col, this.right);
            } else { // right is a Col
                return this._bindColCol(batch, this.left as Col, this.right as Col);
            }
        }
    }

    protected abstract _bindLitLit(batch: RecordBatch, left: Literal, right: Literal): PredicateFunc;
    protected abstract _bindColCol(batch: RecordBatch, left: Col, right: Col): PredicateFunc;
    protected abstract _bindColLit(batch: RecordBatch, col: Col, lit: Literal): PredicateFunc;
    protected abstract _bindLitCol(batch: RecordBatch, lit: Literal, col: Col): PredicateFunc;
}

export abstract class CombinationPredicate extends Predicate {
    constructor(public readonly left: Predicate, public readonly right: Predicate) {
        super();
    }
}

export class And extends CombinationPredicate {
    bind(batch: RecordBatch) {
        const left = this.left.bind(batch);
        const right = this.right.bind(batch);
        return (idx: number, batch: RecordBatch) => left(idx, batch) && right(idx, batch);
    }
    ands(): Predicate[] { return this.left.ands().concat(this.right.ands()); }
}

export class Or extends CombinationPredicate {
    bind(batch: RecordBatch) {
        const left = this.left.bind(batch);
        const right = this.right.bind(batch);
        return (idx: number, batch: RecordBatch) => left(idx, batch) || right(idx, batch);
    }
}

export class Equals extends ComparisonPredicate {
    // Helpers used to cache dictionary reverse lookups between calls to bind
    private lastDictionary: Vector|undefined;
    private lastKey: number|undefined;

    protected _bindLitLit(_batch: RecordBatch, left: Literal, right: Literal): PredicateFunc {
        const rtrn: boolean = left.v == right.v;
        return () => rtrn;
    }

    protected _bindColCol(batch: RecordBatch, left: Col, right: Col): PredicateFunc {
        const left_func = left.bind(batch);
        const right_func = right.bind(batch);
        return (idx: number, batch: RecordBatch) => left_func(idx, batch) == right_func(idx, batch);
    }

    protected _bindColLit(batch: RecordBatch, col: Col, lit: Literal): PredicateFunc {
        const col_func = col.bind(batch);
        if (col.vector instanceof DictionaryVector) {
            let key: any;
            const vector = col.vector as DictionaryVector;
            if (vector.dictionary !== this.lastDictionary) {
                key = vector.reverseLookup(lit.v);
                this.lastDictionary = vector.dictionary;
                this.lastKey = key;
            } else {
                key = this.lastKey;
            }

            if (key === -1) {
                // the value doesn't exist in the dictionary - always return
                // false
                // TODO: special-case of PredicateFunc that encapsulates this
                // "always false" behavior. That way filtering operations don't
                // have to bother checking
                return () => false;
            } else {
                return (idx: number) => {
                    return vector.getKey(idx) === key;
                };
            }
        } else {
            return (idx: number, cols: RecordBatch) => col_func(idx, cols) == lit.v;
        }
    }

    protected _bindLitCol(batch: RecordBatch, lit: Literal, col: Col) {
        // Equals is comutative
        return this._bindColLit(batch, col, lit);
    }
}

export class LTeq extends ComparisonPredicate {
    protected _bindLitLit(_batch: RecordBatch, left: Literal, right: Literal): PredicateFunc {
        const rtrn: boolean = left.v <= right.v;
        return () => rtrn;
    }

    protected _bindColCol(batch: RecordBatch, left: Col, right: Col): PredicateFunc {
        const left_func = left.bind(batch);
        const right_func = right.bind(batch);
        return (idx: number, cols: RecordBatch) => left_func(idx, cols) <= right_func(idx, cols);
    }

    protected _bindColLit(batch: RecordBatch, col: Col, lit: Literal): PredicateFunc {
        const col_func = col.bind(batch);
        return (idx: number, cols: RecordBatch) => col_func(idx, cols) <= lit.v;
    }

    protected _bindLitCol(batch: RecordBatch, lit: Literal, col: Col) {
        const col_func = col.bind(batch);
        return (idx: number, cols: RecordBatch) => lit.v <= col_func(idx, cols);
    }
}

export class GTeq extends ComparisonPredicate {
    protected _bindLitLit(_batch: RecordBatch, left: Literal, right: Literal): PredicateFunc {
        const rtrn: boolean = left.v >= right.v;
        return () => rtrn;
    }

    protected _bindColCol(batch: RecordBatch, left: Col, right: Col): PredicateFunc {
        const left_func = left.bind(batch);
        const right_func = right.bind(batch);
        return (idx: number, cols: RecordBatch) => left_func(idx, cols) >= right_func(idx, cols);
    }

    protected _bindColLit(batch: RecordBatch, col: Col, lit: Literal): PredicateFunc {
        const col_func = col.bind(batch);
        return (idx: number, cols: RecordBatch) => col_func(idx, cols) >= lit.v;
    }

    protected _bindLitCol(batch: RecordBatch, lit: Literal, col: Col) {
        const col_func = col.bind(batch);
        return (idx: number, cols: RecordBatch) => lit.v >= col_func(idx, cols);
    }
}

export class CustomPredicate extends Predicate {
    constructor(private next: PredicateFunc, private bind_: (batch: RecordBatch) => void) {
        super();
    }

    bind(batch: RecordBatch) {
        this.bind_(batch);
        return this.next;
    }
}

export function lit(v: any): Value<any> { return new Literal(v); }
export function col(n: string): Col<any> { return new Col(n); }
export function custom(next: PredicateFunc, bind: (batch: RecordBatch) => void) {
    return new CustomPredicate(next, bind);
}
