"use strict"
Object.defineProperty(exports, "__esModule", { value: true })
exports.withSeed =
  exports.nextRange =
  exports.nextInt =
  exports.nextIntBetween =
  exports.nextBoolean =
  exports.next =
  exports.HasRandom =
  exports.defaultRandom =
  exports.LiveRandom =
  exports.Random =
  exports.RandomSymbol =
    void 0
// tracing: off
/**
 * Ported from https://github.com/zio/zio/blob/master/core/shared/src/main/scala/zio/Random.scala
 *
 * Copyright 2020 Michael Arnaldi and the Matechs Garage Contributors.
 */
require("../Operator")
const core_1 = require("../Effect/core")
const has_1 = require("../Effect/has")
const Has_1 = require("../Has")
const PCG_1 = require("./PCG")
exports.RandomSymbol = Symbol.for("@effect-ts/system/Random")
class Random {
  constructor() {
    this._tag = exports.RandomSymbol
  }
}
exports.Random = Random
class LiveRandom extends Random {
  constructor(seed) {
    super()
    this.next = (0, core_1.succeedWith)(() => this.PRNG.number())
    this.nextBoolean = (0, core_1.chain_)(this.next, (n) =>
      (0, core_1.succeedWith)(() => n > 0.5)
    )
    this.nextInt = (0, core_1.succeedWith)(() => this.PRNG.integer(0))
    this.nextRange = (low, high) =>
      (0, core_1.chain_)(this.next, (n) =>
        (0, core_1.succeedWith)(() => (high - low) * n + low)
      )
    this.nextIntBetween = (low, high) =>
      (0, core_1.succeedWith)(() => this.PRNG.integer(1 + high - low) + low)
    this.PRNG = new PCG_1.PCGRandom(seed)
  }
}
exports.LiveRandom = LiveRandom
exports.defaultRandom = new LiveRandom((Math.random() * 4294967296) >>> 0)
exports.HasRandom = (0, Has_1.tag)(Random).setKey(exports.RandomSymbol)
exports.next = (0, has_1.accessServiceM)(exports.HasRandom)((_) => _.next)
exports.nextBoolean = (0, has_1.accessServiceM)(exports.HasRandom)((_) => _.nextBoolean)
const nextIntBetween = (low, high) =>
  (0, has_1.accessServiceM)(exports.HasRandom)((_) => _.nextIntBetween(low, high))
exports.nextIntBetween = nextIntBetween
exports.nextInt = (0, has_1.accessServiceM)(exports.HasRandom)((_) => _.nextInt)
const nextRange = (low, high) =>
  (0, has_1.accessServiceM)(exports.HasRandom)((_) => _.nextRange(low, high))
exports.nextRange = nextRange
const withSeed = (seed) =>
  (0, has_1.replaceService)(exports.HasRandom, () => new LiveRandom(seed))
exports.withSeed = withSeed
//# sourceMappingURL=index.js.map
