import * as tsplus_module_1 from "@effect/core/stream/Sink/operations/suspend";
import * as tsplus_module_2 from "@effect/core/stream/Channel/operations/succeedNow";
import * as tsplus_module_3 from "@tsplus/stdlib/collections/Chunk/isNonEmpty";
import * as tsplus_module_4 from "@effect/core/stream/Channel/operations/write";
import * as tsplus_module_5 from "@effect/core/stream/Channel/operations/as";
import * as tsplus_module_6 from "@effect/core/stream/Channel/operations/fail";
import * as tsplus_module_7 from "@effect/core/stream/Channel/operations/readWith";
import * as tsplus_module_8 from "@tsplus/stdlib/collections/Chunk/empty";
import * as tsplus_module_9 from "@tsplus/stdlib/data/Tuple/make";
import * as tsplus_module_10 from "@tsplus/stdlib/collections/Chunk/unsafeGet";
import * as tsplus_module_11 from "@tsplus/stdlib/collections/Chunk/drop";
import { SinkInternal } from "@effect/core/stream/Sink/operations/_internal/SinkInternal";
/**
 * A sink that folds its inputs with the provided function, termination
 * predicate and initial state.
 *
 * @tsplus static ets/Sink/Ops fold
 */

export function fold(z, cont, f, __tsplusTrace) {
  return tsplus_module_1.suspend(() => new SinkInternal(reader(z(), cont, f, __tsplusTrace)), __tsplusTrace);
}

function reader(z, cont, f, __tsplusTrace) {
  return !cont(z) ? tsplus_module_2.succeedNow(z) : tsplus_module_7.readWith(chunk => {
    const {
      tuple: [nextS, leftovers]
    } = foldChunkSplit(z, chunk, cont, f, __tsplusTrace);
    return tsplus_module_3.isNonEmpty(leftovers) ? tsplus_module_5.as_(tsplus_module_4.write(() => leftovers), () => nextS) : reader(nextS, cont, f, __tsplusTrace);
  }, err => tsplus_module_6.fail(() => err), () => tsplus_module_2.succeedNow(z));
}

function foldChunkSplit(z, chunk, cont, f, __tsplusTrace) {
  return foldInternal(z, chunk, cont, f, 0, chunk.length, __tsplusTrace);
}

function foldInternal(z, chunk, cont, f, index, length, __tsplusTrace) {
  if (index === length) {
    return tsplus_module_9.make(z, tsplus_module_8.empty());
  }

  const z1 = f(z, tsplus_module_10.unsafeGet_(chunk, index));
  return cont(z1) ? foldInternal(z1, chunk, cont, f, index + 1, length, __tsplusTrace) : tsplus_module_9.make(z1, tsplus_module_11.drop_(chunk, index + 1));
}
//# sourceMappingURL=fold.mjs.map