import * as CK from "../../../../Collections/Immutable/Chunk";
import * as T from "../../../../Effect";
import * as SC from "../../../../Schedule";
import * as CH from "../../Channel";
import * as C from "../core";
/**
 * Schedules the output of the stream using the provided `schedule` and emits its output at
 * the end (if `schedule` is finite).
 * Uses the provided function to align the stream and schedule outputs on the same type.
 */

export function scheduleWith_(self, schedule, f, g) {
  const loop = (driver, chunk, index) => {
    if (index < CK.size(chunk)) {
      return CH.unwrap(T.suspend(() => {
        const a = CK.unsafeGet_(chunk, index);
        return T.foldM_(driver.next(a), () => T.zipLeft_(T.map_(T.orDie(driver.last), b => CH.zipRight_(CH.write(CK.many(f(a), g(b))), loop(driver, chunk, index + 1))), driver.reset), () => T.succeed(CH.zipRight_(CH.write(CK.single(f(a))), loop(driver, chunk, index + 1))));
      }));
    } else {
      return CH.readWithCause(chunk => loop(driver, chunk, 0), _ => CH.failCause(_), _ => CH.end(_));
    }
  };

  return new C.Stream(CH.chain_(CH.fromEffect(SC.driver(schedule)), _ => self.channel[">>>"](loop(_, CK.empty(), 0))));
}
/**
 * Schedules the output of the stream using the provided `schedule` and emits its output at
 * the end (if `schedule` is finite).
 * Uses the provided function to align the stream and schedule outputs on the same type.
 *
 * @ets_data_first scheduleWith_
 */

export function scheduleWith(schedule, f, g) {
  return self => scheduleWith_(self, schedule, f, g);
}
//# sourceMappingURL=scheduleWith.js.map