// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

package desugaredlib.flow;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Flow.Publisher;
import java.util.concurrent.Flow.Subscriber;
import java.util.concurrent.Flow.Subscription;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

public class FlowExample {
  public static void main(String[] args) throws Exception {
    OneShotPublisher oneShotPublisher = new OneShotPublisher();
    SampleSubscriber<Object> subscriber = new SampleSubscriber<>(50L, System.out::println);
    oneShotPublisher.subscribe(subscriber);
    oneShotPublisher.awaitPublishing();
  }

  public static class OneShotPublisher implements Publisher<Boolean> {

    private final ForkJoinPool executor = new ForkJoinPool(); // daemon-based

    private boolean subscribed; // true after first subscribe

    public synchronized void subscribe(Subscriber<? super Boolean> subscriber) {
      if (subscribed) {
        subscriber.onError(new IllegalStateException()); // only one allowed
      } else {
        subscribed = true;
        subscriber.onSubscribe(new OneShotPublisher.OneShotSubscription(subscriber, executor));
      }
    }

    void awaitPublishing() throws InterruptedException {
      // On Android 7 and higher, calling System.exit() terminates all threads without waiting for
      // tasks on the fork join pool to be finished. For the test to be completed we need such
      // tasks to finish.
      int seconds = 60;
      executor.awaitTermination(seconds, TimeUnit.SECONDS);
    }

    static class OneShotSubscription implements Subscription {

      private final Subscriber<? super Boolean> subscriber;
      private final ExecutorService executor;
      private Future<?> future; // to allow cancellation
      private boolean completed;

      OneShotSubscription(Subscriber<? super Boolean> subscriber, ExecutorService executor) {
        this.subscriber = subscriber;
        this.executor = executor;
      }

      public synchronized void request(long n) {
        if (n != 0 && !completed) {
          completed = true;
          if (n < 0) {
            IllegalArgumentException ex = new IllegalArgumentException();
            executor.execute(() -> subscriber.onError(ex));
          } else {
            future =
                executor.submit(
                    () -> {
                      subscriber.onNext(Boolean.TRUE);
                      subscriber.onComplete();
                    });
          }
        }
      }

      public synchronized void cancel() {
        completed = true;
        if (future != null) {
          future.cancel(false);
        }
      }
    }
  }

  static class SampleSubscriber<T> implements Subscriber<T> {

    final Consumer<? super T> consumer;
    Subscription subscription;
    final long bufferSize;
    long count;

    SampleSubscriber(long bufferSize, Consumer<? super T> consumer) {
      this.bufferSize = bufferSize;
      this.consumer = consumer;
    }

    public void onSubscribe(Subscription subscription) {
      long initialRequestSize = bufferSize;
      count = bufferSize - bufferSize / 2; // re-request when half consumed
      (this.subscription = subscription).request(initialRequestSize);
    }

    public void onNext(T item) {
      if (--count <= 0) {
        subscription.request(count = bufferSize - bufferSize / 2);
      }
      consumer.accept(item);
    }

    public void onError(Throwable ex) {
      ex.printStackTrace();
    }

    public void onComplete() {}
  }
}
