"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.splitLines = void 0;
// ets_tracing: off
const CK = __importStar(require("../../../../Collections/Immutable/Chunk"));
const Tp = __importStar(require("../../../../Collections/Immutable/Tuple"));
const Function_1 = require("../../../../Function");
const O = __importStar(require("../../../../Option"));
const CH = __importStar(require("../../Channel"));
const C = __importStar(require("../core"));
/**
 * Splits strings on newlines. Handles both Windows newlines (`\r\n`) and UNIX newlines (`\n`).
 */
function splitLines(self) {
    const next = (leftover, wasSplitCRLF) => CH.readWithCause((incomingChunk) => {
        const buffer = CK.builder();
        let inCRLF = wasSplitCRLF;
        let carry = O.getOrElse_(leftover, () => "");
        CK.forEach_(incomingChunk, (string) => {
            const concatenated = carry + string;
            if (string.length > 0) {
                const continueFrom = inCRLF && carry.length > 0 ? carry.length - 1 : carry.length;
                return ((({ tuple: [sliceStart, _, midCRLF] }) => {
                    carry = concatenated.slice(sliceStart);
                    inCRLF = midCRLF;
                })(CK.reduce_(CK.drop_(CK.zipWithIndex(CK.from(concatenated)), continueFrom), Tp.tuple(0, false, inCRLF), ({ tuple: [sliceStart, skipNext, midCRLF] }, { tuple: [char, index] }) => {
                    if (skipNext) {
                        return Tp.tuple(sliceStart, false, false);
                    }
                    else {
                        switch (char) {
                            case "\n": {
                                buffer.append(concatenated.slice(sliceStart, index));
                                return Tp.tuple(index + 1, false, midCRLF);
                            }
                            case "\r": {
                                if (index + 1 < concatenated.length &&
                                    concatenated[index + 1] === "\n") {
                                    buffer.append(concatenated.slice(sliceStart, index));
                                    return Tp.tuple(index + 2, true, false);
                                }
                                else if (index === concatenated.length - 1) {
                                    return Tp.tuple(sliceStart, false, true);
                                }
                                else {
                                    return Tp.tuple(index, false, false);
                                }
                            }
                            default: {
                                return Tp.tuple(sliceStart, false, midCRLF);
                            }
                        }
                    }
                })));
            }
        });
        return CH.zipRight_(CH.write(buffer.build()), next(carry.length > 0 ? O.some(carry) : O.none, inCRLF));
    }, (halt) => O.fold_(leftover, () => CH.failCause(halt), (value) => CH.zipRight_(CH.write(CK.single(value)), CH.failCause(halt))), (done) => O.fold_(leftover, () => CH.end(done), (value) => CH.zipRight_(CH.write(CK.single(value)), CH.end(done))));
    return new C.Stream(self.channel[">>>"](next(O.none, false)));
}
exports.splitLines = splitLines;
//# sourceMappingURL=splitLines.js.map