"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = Object.setPrototypeOf ||
        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var stream_1 = require("stream");
var Parameters_1 = require("./Parameters");
var ParseRuntime_1 = require("./ParseRuntime");
var bluebird_1 = __importDefault(require("bluebird"));
// import { ProcessorFork } from "./ProcessFork";
var ProcessorLocal_1 = require("./ProcessorLocal");
var Result_1 = require("./Result");
var Converter = /** @class */ (function (_super) {
    __extends(Converter, _super);
    function Converter(param, options) {
        if (options === void 0) { options = {}; }
        var _this = _super.call(this, options) || this;
        _this.options = options;
        _this.params = Parameters_1.mergeParams(param);
        _this.runtime = ParseRuntime_1.initParseRuntime(_this);
        _this.result = new Result_1.Result(_this);
        // if (this.params.fork) {
        //   this.processor = new ProcessorFork(this);
        // } else {
        _this.processor = new ProcessorLocal_1.ProcessorLocal(_this);
        // }
        _this.once("error", function (err) {
            // console.log("BBB");
            setTimeout(function () {
                _this.result.processError(err);
                _this.emit("done", err);
            }, 0);
        });
        _this.once("done", function () {
            _this.processor.destroy();
        });
        return _this;
    }
    Converter.prototype.preRawData = function (onRawData) {
        this.runtime.preRawDataHook = onRawData;
        return this;
    };
    Converter.prototype.preFileLine = function (onFileLine) {
        this.runtime.preFileLineHook = onFileLine;
        return this;
    };
    Converter.prototype.subscribe = function (onNext, onError, onCompleted) {
        this.parseRuntime.subscribe = {
            onNext: onNext,
            onError: onError,
            onCompleted: onCompleted
        };
        return this;
    };
    Converter.prototype.fromFile = function (filePath, options) {
        var _this = this;
        var fs = require("fs");
        // var rs = null;
        // this.wrapCallback(cb, function () {
        //   if (rs && rs.destroy) {
        //     rs.destroy();
        //   }
        // });
        fs.exists(filePath, function (exist) {
            if (exist) {
                var rs = fs.createReadStream(filePath, options);
                rs.pipe(_this);
            }
            else {
                _this.emit('error', new Error("File does not exist. Check to make sure the file path to your csv is correct."));
            }
        });
        return this;
    };
    Converter.prototype.fromStream = function (readStream) {
        readStream.pipe(this);
        return this;
    };
    Converter.prototype.fromString = function (csvString) {
        var csv = csvString.toString();
        var read = new stream_1.Readable();
        var idx = 0;
        read._read = function (size) {
            if (idx >= csvString.length) {
                this.push(null);
            }
            else {
                var str = csvString.substr(idx, size);
                this.push(str);
                idx += size;
            }
        };
        return this.fromStream(read);
    };
    Converter.prototype.then = function (onfulfilled, onrejected) {
        var _this = this;
        return new bluebird_1.default(function (resolve, reject) {
            _this.parseRuntime.then = {
                onfulfilled: function (value) {
                    if (onfulfilled) {
                        resolve(onfulfilled(value));
                    }
                    else {
                        resolve(value);
                    }
                },
                onrejected: function (err) {
                    if (onrejected) {
                        resolve(onrejected(err));
                    }
                    else {
                        reject(err);
                    }
                }
            };
        });
    };
    Object.defineProperty(Converter.prototype, "parseParam", {
        get: function () {
            return this.params;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Converter.prototype, "parseRuntime", {
        get: function () {
            return this.runtime;
        },
        enumerable: true,
        configurable: true
    });
    Converter.prototype._transform = function (chunk, encoding, cb) {
        var _this = this;
        this.processor.process(chunk)
            .then(function (result) {
            // console.log(result);
            if (result.length > 0) {
                _this.runtime.started = true;
                return _this.result.processResult(result);
            }
        })
            .then(function () {
            _this.emit("drained");
            cb();
        }, function (error) {
            _this.runtime.hasError = true;
            _this.runtime.error = error;
            _this.emit("error", error);
            cb();
        });
    };
    Converter.prototype._flush = function (cb) {
        var _this = this;
        this.processor.flush()
            .then(function (data) {
            if (data.length > 0) {
                return _this.result.processResult(data);
            }
        })
            .then(function () {
            _this.processEnd(cb);
        }, function (err) {
            _this.emit("error", err);
            cb();
        });
    };
    Converter.prototype.processEnd = function (cb) {
        this.result.endProcess();
        this.emit("done");
        cb();
    };
    Object.defineProperty(Converter.prototype, "parsedLineNumber", {
        get: function () {
            return this.runtime.parsedLineNumber;
        },
        enumerable: true,
        configurable: true
    });
    return Converter;
}(stream_1.Transform));
exports.Converter = Converter;
//# sourceMappingURL=Converter.js.map