package com.airlock.iam.common.domain.model.state;

import java.time.Duration;
import java.util.Optional;
import lombok.NonNull;

public record StateTimeout(@NonNull Optional<StateDuration> stateIdleTimeout, @NonNull Optional<StateDuration> stateLifetime) {
   public static final StateTimeout MAX_VALUE = timeout(StateDuration.MAX_STATE_DURATION, StateDuration.MAX_STATE_DURATION);

   public StateTimeout {
      if (stateIdleTimeout == null) {
         throw new NullPointerException("stateIdleTimeout is marked non-null but is null");
      }

      if (stateLifetime == null) {
         throw new NullPointerException("stateLifetime is marked non-null but is null");
      }

      if (stateLifetime.isEmpty() && stateIdleTimeout.isEmpty()) {
         throw new IllegalArgumentException("Lifetime and idle timeout cannot both be empty.");
      }
   }

   public Optional<Duration> lifetime() {
      return this.stateLifetime.map(StateDuration::duration);
   }

   public Optional<Duration> idleTimeout() {
      return this.stateIdleTimeout().map(StateDuration::duration);
   }

   public static StateTimeout timeoutWithLifetime(Duration lifetime) {
      return new StateTimeout(Optional.empty(), Optional.of(new StateDuration(lifetime)));
   }

   public static StateTimeout timeoutWithIdleTimeout(Duration idleTimeout) {
      return new StateTimeout(Optional.of(new StateDuration(idleTimeout)), Optional.empty());
   }

   public static StateTimeout timeout(Duration idleTimeout, Duration lifetime) {
      return new StateTimeout(Optional.of(new StateDuration(idleTimeout)), Optional.of(new StateDuration(lifetime)));
   }

   public static StateTimeout timeout(Duration idleTimeout, Optional<Duration> lifetime) {
      return new StateTimeout(Optional.of(new StateDuration(idleTimeout)), lifetime.map(StateDuration::new));
   }
}
