"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var assign = require("lodash/assign");
var cloneDeep = require("lodash/cloneDeep");
var isArray = require("lodash/isArray");
var every = require("lodash/every");
var some = require("lodash/some");
var isPlainObject = require("lodash/isPlainObject");
var pickBy = require("lodash/pickBy");
var forEach = require("lodash/forEach");
var map = require("lodash/map");
var PineTypes_1 = require("../PineTypes");
exports.SIMPLE_SEARCH_NAME = 'Full text search';
var SchemaSieve = (function () {
    function SchemaSieve(tests) {
        if (tests === void 0) { tests = {}; }
        this.tests = assign(cloneDeep(PineTypes_1.default), tests);
        this.SIMPLE_SEARCH_NAME = exports.SIMPLE_SEARCH_NAME;
    }
    SchemaSieve.prototype.test = function (item, input) {
        var _this = this;
        return isArray(input)
            ? every(input, function (i) { return _this.baseTest(item, i); })
            : this.baseTest(item, input);
    };
    SchemaSieve.prototype.baseTest = function (item, input) {
        var type = input.type, name = input.name;
        if (name === exports.SIMPLE_SEARCH_NAME) {
            var value_1 = input.value;
            return some(item, function (target) {
                return target &&
                    String(target)
                        .toLowerCase()
                        .includes(value_1.toLowerCase());
            });
        }
        if (type in PineTypes_1.default) {
            var operator = input.operator, value = input.value;
            var target = item[name];
            if (operator in PineTypes_1.default[type].rules) {
                var result = PineTypes_1.default[type].rules[operator];
                return isPlainObject(result)
                    ? result.test(target, value)
                    : result(target, value);
            }
        }
        return true;
    };
    SchemaSieve.prototype.filter = function (collection, input) {
        if (isArray(collection)) {
            return this.filterArray(collection, input);
        }
        if (isPlainObject(collection)) {
            return this.filterObject(collection, input);
        }
        throw new Error('collection argument must be either object or array.');
    };
    SchemaSieve.prototype.filterArray = function (collection, input) {
        var _this = this;
        return collection.filter(function (item) { return _this.test(item, input); });
    };
    SchemaSieve.prototype.filterObject = function (collection, input) {
        var _this = this;
        return pickBy(collection, function (value) { return _this.test(value, input); });
    };
    SchemaSieve.prototype.getOperators = function (type, schemaEntry) {
        if (type in PineTypes_1.default) {
            return map(PineTypes_1.default[type].rules, function (value, key) {
                if (isPlainObject(value) && value.getLabel) {
                    var label = value.getLabel(schemaEntry);
                    if (label) {
                        return {
                            label: label,
                            value: key
                        };
                    }
                }
                return {
                    label: key,
                    value: key
                };
            });
        }
        return [];
    };
    SchemaSieve.prototype.makeFilterInputs = function (schema) {
        var _this = this;
        var inputs = {};
        forEach(schema, function (value, key) {
            inputs[key] = {
                type: value.type,
                name: key,
                label: value.label,
                availableOperators: _this.getOperators(value.type, schema[key]),
                operator: null,
                value: null
            };
        });
        return inputs;
    };
    SchemaSieve.prototype.validate = function (type, value) {
        if (!(type in PineTypes_1.default)) {
            return true;
        }
        return PineTypes_1.default[type].validate(value);
    };
    SchemaSieve.prototype.getTypes = function () {
        return Object.keys(PineTypes_1.default);
    };
    return SchemaSieve;
}());
exports.default = function (tests) { return new SchemaSieve(tests); };
