package com.airlock.iam.authentication.domain.model.event;

import com.airlock.iam.base.api.domain.model.event.EventId;
import com.airlock.iam.base.api.domain.model.event.EventType;
import com.airlock.iam.base.api.domain.model.event.metadata.EventMetadata;
import com.airlock.iam.base.api.domain.model.event.source.EventSource;
import com.airlock.iam.base.api.domain.model.user.UserId;
import com.airlock.iam.base.domain.model.event.EventCreationData;
import com.airlock.iam.common.api.domain.model.event.LoginFromNewDeviceEvent;
import com.airlock.iam.common.api.domain.model.geolocation.Geolocation;
import com.airlock.iam.flow.domain.model.event.FlowEventTypes;
import com.airlock.iam.flow.shared.domain.model.newdevice.LoginFromNewDeviceUserAgent;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.time.Instant;
import java.util.Optional;
import lombok.NonNull;

public final class LoginFromNewDeviceEventImpl implements LoginFromNewDeviceEvent {
   @NonNull
   private final EventCreationData eventCreationData;
   @NonNull
   private final UserId userId;
   @NonNull
   private final Optional<LoginFromNewDeviceUserAgent> userAgent;
   @NonNull
   private final Optional<Geolocation> geolocation;

   @Override
   public EventId id() {
      return this.eventCreationData.id();
   }

   @Override
   public Instant createdAt() {
      return this.eventCreationData.createdAt();
   }

   @Override
   public EventSource source() {
      return this.eventCreationData.source();
   }

   @Override
   public EventMetadata metadata() {
      return this.eventCreationData.metadata();
   }

   @Override
   public String browser() {
      return this.userAgent.flatMap(LoginFromNewDeviceUserAgent::browser).orElse("");
   }

   @Override
   public String operatingSystem() {
      return this.userAgent.flatMap(LoginFromNewDeviceUserAgent::operatingSystem).orElse("");
   }

   @Override
   public String device() {
      return this.userAgent.flatMap(LoginFromNewDeviceUserAgent::device).orElse("");
   }

   @Override
   public String countryCode() {
      return this.geolocation.flatMap(Geolocation::getCountryCode).orElse("");
   }

   @Override
   public String city() {
      return this.geolocation.flatMap(Geolocation::getCity).orElse("");
   }

   @Override
   public String displayName() {
      return "Login from New Device";
   }

   @Override
   public EventType type() {
      return FlowEventTypes.LOGIN_FROM_NEW_DEVICE;
   }

   @SuppressFBWarnings(justification = "generated code")
   public LoginFromNewDeviceEventImpl(
      @NonNull EventCreationData eventCreationData,
      @NonNull UserId userId,
      @NonNull Optional<LoginFromNewDeviceUserAgent> userAgent,
      @NonNull Optional<Geolocation> geolocation
   ) {
      if (eventCreationData == null) {
         throw new NullPointerException("eventCreationData is marked non-null but is null");
      }

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

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

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

      this.eventCreationData = eventCreationData;
      this.userId = userId;
      this.userAgent = userAgent;
      this.geolocation = geolocation;
   }

   @NonNull
   @SuppressFBWarnings(justification = "generated code")
   public EventCreationData eventCreationData() {
      return this.eventCreationData;
   }

   @NonNull
   @SuppressFBWarnings(justification = "generated code")
   @Override
   public UserId userId() {
      return this.userId;
   }

   @NonNull
   @SuppressFBWarnings(justification = "generated code")
   public Optional<LoginFromNewDeviceUserAgent> userAgent() {
      return this.userAgent;
   }

   @NonNull
   @SuppressFBWarnings(justification = "generated code")
   public Optional<Geolocation> geolocation() {
      return this.geolocation;
   }

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

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

   @SuppressFBWarnings(justification = "generated code")
   @Override
   public String toString() {
      return "LoginFromNewDeviceEventImpl(eventCreationData="
         + this.eventCreationData()
         + ", userId="
         + this.userId()
         + ", userAgent="
         + this.userAgent()
         + ", geolocation="
         + this.geolocation()
         + ")";
   }
}
