package com.airlock.iam.factor.domain.model.airlock2fa;

import com.airlock.iam.airlock2fa.api.domain.model.Airlock2FADeviceId;
import com.airlock.iam.base.api.domain.model.exception.FailureException;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;

public final class Airlock2FADevices implements Iterable<Airlock2FAAuthDevice> {
   private final List<Airlock2FAAuthDevice> devices;

   public static Airlock2FADevices of(Airlock2FAAuthDevice... device) {
      return new Airlock2FADevices(List.of(device));
   }

   public static Airlock2FADevices of(Collection<Airlock2FAAuthDevice> devices) {
      return new Airlock2FADevices(devices);
   }

   private Airlock2FADevices(Collection<Airlock2FAAuthDevice> devices) {
      this.devices = List.copyOf(devices);
   }

   public Optional<Airlock2FAAuthDevice> deviceWithId(Airlock2FADeviceId deviceId) {
      return this.stream().filter(device -> device.getId().equals(deviceId)).findFirst();
   }

   public boolean containsDeviceWithId(Airlock2FADeviceId deviceId) {
      return this.deviceWithId(deviceId).isPresent();
   }

   public int size() {
      return this.devices.size();
   }

   public Airlock2FAAuthDevice onlyDeviceOrThrow() {
      if (!this.hasOneDevice()) {
         throw new FailureException("expected exactly one device");
      } else {
         return this.devices.getFirst();
      }
   }

   public boolean hasOneDevice() {
      return this.size() == 1;
   }

   public Optional<Airlock2FAAuthDevice> firstDevice() {
      return this.stream().findFirst();
   }

   public Stream<Airlock2FAAuthDevice> stream() {
      return this.devices.stream();
   }

   @Override
   public Iterator<Airlock2FAAuthDevice> iterator() {
      return this.devices.iterator();
   }

   public boolean isEmpty() {
      return this.devices.isEmpty();
   }

   public Airlock2FAAuthDevice get(int i) {
      return this.devices.get(i);
   }

   @SuppressFBWarnings(justification = "generated code")
   @Override
   public boolean equals(Object o) {
      if (o == this) {
         return true;
      } else if (!(o instanceof Airlock2FADevices other)) {
         return false;
      } else {
         Object this$devices = this.devices;
         Object other$devices = other.devices;
         return this$devices == null ? other$devices == null : this$devices.equals(other$devices);
      }
   }

   @SuppressFBWarnings(justification = "generated code")
   @Override
   public int hashCode() {
      int PRIME = 59;
      int result = 1;
      Object $devices = this.devices;
      return result * 59 + ($devices == null ? 43 : $devices.hashCode());
   }
}
