"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.zipRight =
  exports.zipRight_ =
  exports.zipLeft =
  exports.zipLeft_ =
  exports.zip =
  exports.zip_ =
  exports.zipWith =
  exports.zipWith_ =
  exports.map =
  exports.map_ =
  exports.toCause =
  exports.flatten =
  exports.chain =
  exports.chain_ =
  exports.fold =
  exports.fold_ =
  exports.first =
    void 0
const tracing_1 = __importStar(require("../../../Tracing"))
const fileName_1 = "(@effect-ts/system): _src/Collections/Immutable/ParSeq/core.ts"
const Cause = __importStar(require("../../../Cause/core"))
const E = __importStar(require("../../../Either"))
const Function_1 = require("../../../Function")
const O = __importStar(require("../../../Option"))
const L = __importStar(require("../List/core"))
const Tp = __importStar(require("../Tuple"))
const P = __importStar(require("./primitives"))
/**
 * Returns the first event in this collection of events. If multiple events
 * occur in parallel and before any other events then any of these events
 * may be returned.
 */
function first(self) {
  // eslint-disable-next-line no-constant-condition
  while (1) {
    switch (self._tag) {
      case "Single": {
        return O.some(self.a)
      }
      case "Empty": {
        return O.none
      }
      case "Both": {
        self = self.left
        break
      }
      case "Then": {
        self = self.left
        break
      }
    }
  }
  throw new Error("Bug")
}
exports.first = first
function foldLoop(emptyCase, singleCase, thenCase, bothCase, inp, out) {
  // eslint-disable-next-line no-constant-condition
  while (1) {
    if (L.isEmpty(inp)) {
      return L.reduce_(out, L.empty(), (acc, val) => {
        if (val._tag === "Right") {
          return L.prepend_(acc, val.right)
        } else {
          if (val.left) {
            let parSeqs = acc
            const left = L.unsafeFirst(parSeqs)
            parSeqs = L.tail(parSeqs)
            const right = L.unsafeFirst(parSeqs)
            parSeqs = L.tail(parSeqs)
            return L.prepend_(parSeqs, bothCase(left, right))
          } else {
            let parSeqs = acc
            const left = L.unsafeFirst(parSeqs)
            parSeqs = L.tail(parSeqs)
            const right = L.unsafeFirst(parSeqs)
            parSeqs = L.tail(parSeqs)
            return L.prepend_(parSeqs, thenCase(left, right))
          }
        }
      })
    } else {
      const head = L.unsafeFirst(inp)
      const parSeqs = L.tail(inp)
      switch (head._tag) {
        case "Empty": {
          inp = parSeqs
          out = L.prepend_(out, E.right(emptyCase))
          break
        }
        case "Single": {
          inp = parSeqs
          out = L.prepend_(out, E.right(singleCase(head.a)))
          break
        }
        case "Then": {
          inp = L.prepend_(L.prepend_(parSeqs, head.right), head.left)
          out = L.prepend_(out, E.left(false))
          break
        }
        case "Both": {
          inp = L.prepend_(L.prepend_(parSeqs, head.right), head.left)
          out = L.prepend_(out, E.left(true))
          break
        }
      }
    }
  }
  throw new Error("Bug")
}
/**
 * Folds over the events in this collection of events using the specified
 * functions.
 */
function fold_(self, emptyCase, singleCase, thenCase, bothCase) {
  return L.unsafeFirst(
    foldLoop(emptyCase, singleCase, thenCase, bothCase, L.of(self), L.empty())
  )
}
exports.fold_ = fold_
/**
 * Folds over the events in this collection of events using the specified
 * functions.
 *
 * @dataFirst fold_
 */
function fold(emptyCase, singleCase, thenCase, bothCase) {
  return (self) => fold_(self, emptyCase, singleCase, thenCase, bothCase)
}
exports.fold = fold
/**
 * Constructs a new collection of events for each event in this collection of
 * events, collecting them back into a single collection of events.
 */
function chain_(self, f) {
  return fold_(self, P.empty, f, P.then_, P.both_)
}
exports.chain_ = chain_
/**
 * Constructs a new collection of events for each event in this collection of
 * events, collecting them back into a single collection of events.
 *
 * @dataFirst chain_
 */
function chain(f) {
  return (self) => chain_(self, f)
}
exports.chain = chain
/**
 * Flattens a collection of collections of events into a single collection
 * of events.
 */
function flatten(self) {
  return chain_(self, Function_1.identity)
}
exports.flatten = flatten
/**
 * Converts a ParSeq to a Cause
 */
function toCause(self) {
  return fold_(self, Cause.empty, Cause.fail, Cause.then, Cause.both)
}
exports.toCause = toCause
/**
 * Transforms the type of events in this collection of events with the
 * specified function.
 */
function map_(self, f) {
  return chain_(self, (a) => P.single(f(a)))
}
exports.map_ = map_
/**
 * Transforms the type of events in this collection of events with the
 * specified function.
 *
 * @dataFirst map_
 */
function map(f) {
  return (self) => map_(self, f)
}
exports.map = map
/**
 * Combines this collection of events with that collection of events to
 * return the Cartesian product of events using the specified function.
 */
function zipWith_(self, that, f) {
  return chain_(self, (a) => map_(that, (b) => f(a, b)))
}
exports.zipWith_ = zipWith_
/**
 * Combines this collection of events with that collection of events to
 * return the Cartesian product of events using the specified function.
 *
 * @dataFirst zipWith_
 */
function zipWith(that, f) {
  return (self) => zipWith_(self, that, f)
}
exports.zipWith = zipWith
/**
 * Combines this collection of events with that collection of events to
 * return the Cartesian product of events, combining the elements into a
 * tuple.
 */
function zip_(self, that) {
  return zipWith_(self, that, Tp.tuple)
}
exports.zip_ = zip_
/**
 * Combines this collection of events with that collection of events to
 * return the Cartesian product of events, combining the elements into a
 * tuple.
 *
 * @dataFirst zip_
 */
function zip(that) {
  return (self) => zip_(self, that)
}
exports.zip = zip
/**
 * Combines this collection of events with that collection of events to
 * return the Cartesian product of events, keeping only the events from this
 * collection.
 */
function zipLeft_(self, that) {
  return zipWith_(self, that, (a, _b) => a)
}
exports.zipLeft_ = zipLeft_
/**
 * Combines this collection of events with that collection of events to
 * return the Cartesian product of events, keeping only the events from this
 * collection.
 *
 * @dataFirst zipLeft_
 */
function zipLeft(that) {
  return (self) => zipLeft_(self, that)
}
exports.zipLeft = zipLeft
/**
 * Combines this collection of events with that collection of events to
 * return the Cartesian product of events, keeping only the events from that
 * collection.
 */
function zipRight_(self, that) {
  return zipWith_(self, that, (_a, b) => b)
}
exports.zipRight_ = zipRight_
/**
 * Combines this collection of events with that collection of events to
 * return the Cartesian product of events, keeping only the events from that
 * collection.
 *
 * @dataFirst zipRight_
 */
function zipRight(that) {
  return (self) => zipRight_(self, that)
}
exports.zipRight = zipRight
//# sourceMappingURL=core.js.map
