package com.example;

import akka.actor.typed.ActorRef;
import akka.actor.typed.Behavior;
import akka.actor.typed.javadsl.*;

import java.util.Objects;

// #greeter
public class Greeter extends AbstractBehavior<Greeter.Greet> {

  public static final class Greet {
    public final String whom;
    public final ActorRef<Greeted> replyTo;

    public Greet(String whom, ActorRef<Greeted> replyTo) {
      this.whom = whom;
      this.replyTo = replyTo;
    }
  }

  public static final class Greeted {
    public final String whom;
    public final ActorRef<Greet> from;

    public Greeted(String whom, ActorRef<Greet> from) {
      this.whom = whom;
      this.from = from;
    }

// #greeter
    @Override
    public boolean equals(Object o) {
      if (this == o) return true;
      if (o == null || getClass() != o.getClass()) return false;
      Greeted greeted = (Greeted) o;
      return Objects.equals(whom, greeted.whom) &&
              Objects.equals(from, greeted.from);
    }

    @Override
    public int hashCode() {
      return Objects.hash(whom, from);
    }

    @Override
    public String toString() {
      return "Greeted{" +
              "whom='" + whom + '\'' +
              ", from=" + from +
              '}';
    }
// #greeter
  }

  private final int max;
  private int greetingCounter;

  public static Behavior<Greet> create(int max) {
    return Behaviors.setup(context -> new Greeter(context, max));
  }

  private Greeter(ActorContext<Greet> context, int max) {
    super(context);
    this.max = max;
  }

  @Override
  public Receive<Greet> createReceive() {
    return newReceiveBuilder().onMessage(Greet.class, this::onGreet).build();
  }

  private Behavior<Greet> onGreet(Greet command) {
    this.greetingCounter++;
    getContext().getLog().info("Hello {}! ({})", command.whom, this.greetingCounter);
    if (this.greetingCounter == max) {
      return Behaviors.stopped();
    } else {
      //#greeter-send-message
      command.replyTo.tell(new Greeted(command.whom, getContext().getSelf()));
      //#greeter-send-message
      return this;
    }
  }
}
// #greeter

