import * as tsplus_module_1 from "@effect/core/stm/TRef/operations/unsafeGet";
import * as tsplus_module_2 from "@effect/core/stm/THub/operations/THub/capacity";
import * as tsplus_module_3 from "@effect/core/stm/TRef/operations/unsafeMake";
import * as tsplus_module_4 from "@effect/core/stm/THub/definition";
import * as tsplus_module_5 from "@effect/core/stm/THub/operations/_internal/InternalNode";
import * as tsplus_module_6 from "@effect/core/stm/TRef/operations/unsafeSet";
import * as tsplus_module_7 from "@effect/core/stm/THub/definition/THub";
import * as tsplus_module_8 from "@effect/core/stm/STM/operations/effect";
import { STMInterruptException, STMRetryException } from "@effect/core/stm/STM";
import { concreteTHub } from "@effect/core/stm/THub/operations/_internal/InternalTHub";
/**
 * Publishes a value to the hub, returning whether the value was published to the
 * queue.
 *
 * @tsplus fluent ets/THub publish
 */

export function publish_(self, a) {
  void 0;
  return tsplus_module_8.effect((journal, fiberId) => {
    const currentPublisherTail = tsplus_module_1.unsafeGet_(self.publisherTail, journal);

    if (currentPublisherTail == null) {
      throw new STMInterruptException(fiberId);
    }

    const currentSubscriberCount = tsplus_module_1.unsafeGet_(self.subscriberCount, journal);

    if (currentSubscriberCount === 0) {
      return true;
    }

    const currentHubSize = tsplus_module_1.unsafeGet_(self.hubSize, journal);

    if (currentHubSize < tsplus_module_2.capacity(self)) {
      const updatedPublisherTail = tsplus_module_3.unsafeMake(undefined);
      const updatedNode = tsplus_module_5.make(a, currentSubscriberCount, updatedPublisherTail);
      tsplus_module_6.unsafeSet_(currentPublisherTail, updatedNode, journal);
      tsplus_module_6.unsafeSet_(self.publisherTail, updatedPublisherTail, journal);
      tsplus_module_6.unsafeSet_(self.hubSize, currentHubSize + 1, journal);
      return true;
    }

    switch (self.strategy) {
      case tsplus_module_7.BackPressure:
        throw new STMRetryException();

      case tsplus_module_7.Dropping:
        return false;

      case tsplus_module_7.Sliding:
        {
          if (tsplus_module_2.capacity(self) > 0) {
            let currentPublisherHead = tsplus_module_1.unsafeGet_(self.publisherHead, journal);
            let loop = true;

            while (loop) {
              const node = tsplus_module_1.unsafeGet_(currentPublisherHead, journal);

              if (node == null) {
                throw new STMRetryException();
              } else {
                const head = node.head;
                const tail = node.tail;

                if (head != null) {
                  const updatedNode = tsplus_module_5.make(undefined, node.subscribers, node.tail);
                  tsplus_module_6.unsafeSet_(currentPublisherHead, updatedNode, journal);
                  tsplus_module_6.unsafeSet_(self.publisherHead, tail, journal);
                  loop = false;
                } else {
                  currentPublisherHead = tail;
                }
              }
            }

            const updatedPublisherTail = tsplus_module_3.unsafeMake(undefined);
            const updatedNode = tsplus_module_5.make(a, currentSubscriberCount, updatedPublisherTail);
            tsplus_module_6.unsafeSet_(currentPublisherTail, updatedNode, journal);
            tsplus_module_6.unsafeSet_(self.publisherTail, updatedPublisherTail, journal);
          }

          return true;
        }
    }

    return false;
  });
}
/**
 * Publishes a value to the hub, returning whether the value was published to the
 * queue.
 *
 * @tsplus static ets/THub/Aspects publish
 */

export const publish = a => self => publish_(self, a);
//# sourceMappingURL=publish.mjs.map