"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const lodash_isfunction_1 = __importDefault(require("lodash.isfunction"));
const types_1 = require("../types");
class RowTransformerValidator {
    constructor() {
        this._rowTransform = null;
        this._rowValidator = null;
    }
    static createTransform(transformFunction) {
        if (types_1.isSyncTransform(transformFunction)) {
            return (row, cb) => {
                let transformed = null;
                try {
                    transformed = transformFunction(row);
                }
                catch (e) {
                    return cb(e);
                }
                return cb(null, transformed);
            };
        }
        return transformFunction;
    }
    static createValidator(validateFunction) {
        if (types_1.isSyncValidate(validateFunction)) {
            return (row, cb) => {
                cb(null, { row, isValid: validateFunction(row) });
            };
        }
        return (row, cb) => {
            validateFunction(row, (err, isValid, reason) => {
                if (err) {
                    return cb(err);
                }
                if (isValid) {
                    return cb(null, { row, isValid, reason });
                }
                return cb(null, { row, isValid: false, reason });
            });
        };
    }
    set rowTransform(transformFunction) {
        if (!lodash_isfunction_1.default(transformFunction)) {
            throw new TypeError('The transform should be a function');
        }
        this._rowTransform = RowTransformerValidator.createTransform(transformFunction);
    }
    set rowValidator(validateFunction) {
        if (!lodash_isfunction_1.default(validateFunction)) {
            throw new TypeError('The validate should be a function');
        }
        this._rowValidator = RowTransformerValidator.createValidator(validateFunction);
    }
    transformAndValidate(row, cb) {
        return this.callTransformer(row, (transformErr, transformedRow) => {
            if (transformErr) {
                return cb(transformErr);
            }
            if (!transformedRow) {
                return cb(null, { row: null, isValid: true });
            }
            return this.callValidator(transformedRow, (validateErr, validationResult) => {
                if (validateErr) {
                    return cb(validateErr);
                }
                if (validationResult && !validationResult.isValid) {
                    return cb(null, { row: transformedRow, isValid: false, reason: validationResult.reason });
                }
                return cb(null, { row: transformedRow, isValid: true });
            });
        });
    }
    callTransformer(row, cb) {
        if (!this._rowTransform) {
            return cb(null, row);
        }
        return this._rowTransform(row, cb);
    }
    callValidator(row, cb) {
        if (!this._rowValidator) {
            return cb(null, { row, isValid: true });
        }
        return this._rowValidator(row, cb);
    }
}
exports.default = RowTransformerValidator;
//# sourceMappingURL=RowTransformerValidator.js.map