package com.airlock.iam.application.webserver.infrastructure.logs;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jakarta.annotation.Nullable;
import lombok.NonNull;

@JsonInclude(Include.NON_NULL)
@JsonPropertyOrder(
   {"time", "timestamp", "program", "priority", "logger_name", "source_class", "source_method", "message", "exception", "thread", "sequence_number", "label"}
)
public class StructuredWebserverLog {
   @JsonProperty("time")
   @NonNull
   private String time;
   @JsonProperty("timestamp")
   @NonNull
   private String timestamp;
   @JsonProperty("program")
   @NonNull
   private final String program;
   @JsonProperty("priority")
   @NonNull
   private String level;
   @JsonProperty("sequence_number")
   private long sequenceNumber;
   @JsonProperty("thread")
   private long threadId;
   @JsonProperty("logger_name")
   @Nullable
   private String loggerName;
   @JsonProperty("source_class")
   @Nullable
   private String sourceClass;
   @JsonProperty("source_method")
   @Nullable
   private String sourceMethod;
   @JsonProperty("message")
   @Nullable
   private String message;
   @JsonProperty("exception")
   @Nullable
   private String exception;
   @JsonProperty("label")
   @Nullable
   private String label;

   @SuppressFBWarnings(justification = "generated code")
   StructuredWebserverLog(
      @NonNull String time,
      @NonNull String timestamp,
      @NonNull String program,
      @NonNull String level,
      long sequenceNumber,
      long threadId,
      @Nullable String loggerName,
      @Nullable String sourceClass,
      @Nullable String sourceMethod,
      @Nullable String message,
      @Nullable String exception,
      @Nullable String label
   ) {
      if (time == null) {
         throw new NullPointerException("time is marked non-null but is null");
      }

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

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

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

      this.time = time;
      this.timestamp = timestamp;
      this.program = program;
      this.level = level;
      this.sequenceNumber = sequenceNumber;
      this.threadId = threadId;
      this.loggerName = loggerName;
      this.sourceClass = sourceClass;
      this.sourceMethod = sourceMethod;
      this.message = message;
      this.exception = exception;
      this.label = label;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static StructuredWebserverLog.StructuredWebserverLogBuilder builder() {
      return new StructuredWebserverLog.StructuredWebserverLogBuilder();
   }

   @NonNull
   @SuppressFBWarnings(justification = "generated code")
   public String getTime() {
      return this.time;
   }

   @NonNull
   @SuppressFBWarnings(justification = "generated code")
   public String getTimestamp() {
      return this.timestamp;
   }

   @NonNull
   @SuppressFBWarnings(justification = "generated code")
   public String getProgram() {
      return this.program;
   }

   @NonNull
   @SuppressFBWarnings(justification = "generated code")
   public String getLevel() {
      return this.level;
   }

   @SuppressFBWarnings(justification = "generated code")
   public long getSequenceNumber() {
      return this.sequenceNumber;
   }

   @SuppressFBWarnings(justification = "generated code")
   public long getThreadId() {
      return this.threadId;
   }

   @Nullable
   @SuppressFBWarnings(justification = "generated code")
   public String getLoggerName() {
      return this.loggerName;
   }

   @Nullable
   @SuppressFBWarnings(justification = "generated code")
   public String getSourceClass() {
      return this.sourceClass;
   }

   @Nullable
   @SuppressFBWarnings(justification = "generated code")
   public String getSourceMethod() {
      return this.sourceMethod;
   }

   @Nullable
   @SuppressFBWarnings(justification = "generated code")
   public String getMessage() {
      return this.message;
   }

   @Nullable
   @SuppressFBWarnings(justification = "generated code")
   public String getException() {
      return this.exception;
   }

   @Nullable
   @SuppressFBWarnings(justification = "generated code")
   public String getLabel() {
      return this.label;
   }

   @SuppressFBWarnings(justification = "generated code")
   public void setTime(@NonNull String time) {
      if (time == null) {
         throw new NullPointerException("time is marked non-null but is null");
      }

      this.time = time;
   }

   @SuppressFBWarnings(justification = "generated code")
   public void setTimestamp(@NonNull String timestamp) {
      if (timestamp == null) {
         throw new NullPointerException("timestamp is marked non-null but is null");
      }

      this.timestamp = timestamp;
   }

   @SuppressFBWarnings(justification = "generated code")
   public void setLevel(@NonNull String level) {
      if (level == null) {
         throw new NullPointerException("level is marked non-null but is null");
      }

      this.level = level;
   }

   @SuppressFBWarnings(justification = "generated code")
   public void setSequenceNumber(long sequenceNumber) {
      this.sequenceNumber = sequenceNumber;
   }

   @SuppressFBWarnings(justification = "generated code")
   public void setThreadId(long threadId) {
      this.threadId = threadId;
   }

   @SuppressFBWarnings(justification = "generated code")
   public void setLoggerName(@Nullable String loggerName) {
      this.loggerName = loggerName;
   }

   @SuppressFBWarnings(justification = "generated code")
   public void setSourceClass(@Nullable String sourceClass) {
      this.sourceClass = sourceClass;
   }

   @SuppressFBWarnings(justification = "generated code")
   public void setSourceMethod(@Nullable String sourceMethod) {
      this.sourceMethod = sourceMethod;
   }

   @SuppressFBWarnings(justification = "generated code")
   public void setMessage(@Nullable String message) {
      this.message = message;
   }

   @SuppressFBWarnings(justification = "generated code")
   public void setException(@Nullable String exception) {
      this.exception = exception;
   }

   @SuppressFBWarnings(justification = "generated code")
   public void setLabel(@Nullable String label) {
      this.label = label;
   }

   @SuppressFBWarnings(justification = "generated code")
   @Override
   public boolean equals(Object o) {
      if (o == this) {
         return true;
      } else if (!(o instanceof StructuredWebserverLog other)) {
         return false;
      } else {
         if (!other.canEqual(this)) {
            return false;
         }

         if (this.sequenceNumber != other.sequenceNumber) {
            return false;
         }

         if (this.threadId != other.threadId) {
            return false;
         }

         Object this$time = this.time;
         Object other$time = other.time;
         if (this$time == null ? other$time == null : this$time.equals(other$time)) {
            Object this$timestamp = this.timestamp;
            Object other$timestamp = other.timestamp;
            if (this$timestamp == null ? other$timestamp == null : this$timestamp.equals(other$timestamp)) {
               Object this$program = this.program;
               Object other$program = other.program;
               if (this$program == null ? other$program == null : this$program.equals(other$program)) {
                  Object this$level = this.level;
                  Object other$level = other.level;
                  if (this$level == null ? other$level == null : this$level.equals(other$level)) {
                     Object this$loggerName = this.loggerName;
                     Object other$loggerName = other.loggerName;
                     if (this$loggerName == null ? other$loggerName == null : this$loggerName.equals(other$loggerName)) {
                        Object this$sourceClass = this.sourceClass;
                        Object other$sourceClass = other.sourceClass;
                        if (this$sourceClass == null ? other$sourceClass == null : this$sourceClass.equals(other$sourceClass)) {
                           Object this$sourceMethod = this.sourceMethod;
                           Object other$sourceMethod = other.sourceMethod;
                           if (this$sourceMethod == null ? other$sourceMethod == null : this$sourceMethod.equals(other$sourceMethod)) {
                              Object this$message = this.message;
                              Object other$message = other.message;
                              if (this$message == null ? other$message == null : this$message.equals(other$message)) {
                                 Object this$exception = this.exception;
                                 Object other$exception = other.exception;
                                 if (this$exception == null ? other$exception == null : this$exception.equals(other$exception)) {
                                    Object this$label = this.label;
                                    Object other$label = other.label;
                                    return this$label == null ? other$label == null : this$label.equals(other$label);
                                 } else {
                                    return false;
                                 }
                              } else {
                                 return false;
                              }
                           } else {
                              return false;
                           }
                        } else {
                           return false;
                        }
                     } else {
                        return false;
                     }
                  } else {
                     return false;
                  }
               } else {
                  return false;
               }
            } else {
               return false;
            }
         } else {
            return false;
         }
      }
   }

   @SuppressFBWarnings(justification = "generated code")
   protected boolean canEqual(Object other) {
      return other instanceof StructuredWebserverLog;
   }

   @SuppressFBWarnings(justification = "generated code")
   @Override
   public int hashCode() {
      int PRIME = 59;
      int result = 1;
      long $sequenceNumber = this.sequenceNumber;
      result = result * 59 + (int)($sequenceNumber >>> 32 ^ $sequenceNumber);
      long $threadId = this.threadId;
      result = result * 59 + (int)($threadId >>> 32 ^ $threadId);
      Object $time = this.time;
      result = result * 59 + ($time == null ? 43 : $time.hashCode());
      Object $timestamp = this.timestamp;
      result = result * 59 + ($timestamp == null ? 43 : $timestamp.hashCode());
      Object $program = this.program;
      result = result * 59 + ($program == null ? 43 : $program.hashCode());
      Object $level = this.level;
      result = result * 59 + ($level == null ? 43 : $level.hashCode());
      Object $loggerName = this.loggerName;
      result = result * 59 + ($loggerName == null ? 43 : $loggerName.hashCode());
      Object $sourceClass = this.sourceClass;
      result = result * 59 + ($sourceClass == null ? 43 : $sourceClass.hashCode());
      Object $sourceMethod = this.sourceMethod;
      result = result * 59 + ($sourceMethod == null ? 43 : $sourceMethod.hashCode());
      Object $message = this.message;
      result = result * 59 + ($message == null ? 43 : $message.hashCode());
      Object $exception = this.exception;
      result = result * 59 + ($exception == null ? 43 : $exception.hashCode());
      Object $label = this.label;
      return result * 59 + ($label == null ? 43 : $label.hashCode());
   }

   @SuppressFBWarnings(justification = "generated code")
   @Override
   public String toString() {
      return "StructuredWebserverLog(time="
         + this.getTime()
         + ", timestamp="
         + this.getTimestamp()
         + ", program="
         + this.getProgram()
         + ", level="
         + this.getLevel()
         + ", sequenceNumber="
         + this.getSequenceNumber()
         + ", threadId="
         + this.getThreadId()
         + ", loggerName="
         + this.getLoggerName()
         + ", sourceClass="
         + this.getSourceClass()
         + ", sourceMethod="
         + this.getSourceMethod()
         + ", message="
         + this.getMessage()
         + ", exception="
         + this.getException()
         + ", label="
         + this.getLabel()
         + ")";
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class StructuredWebserverLogBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private String time;
      @SuppressFBWarnings(justification = "generated code")
      private String timestamp;
      @SuppressFBWarnings(justification = "generated code")
      private String program;
      @SuppressFBWarnings(justification = "generated code")
      private String level;
      @SuppressFBWarnings(justification = "generated code")
      private long sequenceNumber;
      @SuppressFBWarnings(justification = "generated code")
      private long threadId;
      @SuppressFBWarnings(justification = "generated code")
      private String loggerName;
      @SuppressFBWarnings(justification = "generated code")
      private String sourceClass;
      @SuppressFBWarnings(justification = "generated code")
      private String sourceMethod;
      @SuppressFBWarnings(justification = "generated code")
      private String message;
      @SuppressFBWarnings(justification = "generated code")
      private String exception;
      @SuppressFBWarnings(justification = "generated code")
      private String label;

      @SuppressFBWarnings(justification = "generated code")
      StructuredWebserverLogBuilder() {
      }

      @JsonProperty("time")
      @SuppressFBWarnings(justification = "generated code")
      public StructuredWebserverLog.StructuredWebserverLogBuilder time(@NonNull String time) {
         if (time == null) {
            throw new NullPointerException("time is marked non-null but is null");
         }

         this.time = time;
         return this;
      }

      @JsonProperty("timestamp")
      @SuppressFBWarnings(justification = "generated code")
      public StructuredWebserverLog.StructuredWebserverLogBuilder timestamp(@NonNull String timestamp) {
         if (timestamp == null) {
            throw new NullPointerException("timestamp is marked non-null but is null");
         }

         this.timestamp = timestamp;
         return this;
      }

      @JsonProperty("program")
      @SuppressFBWarnings(justification = "generated code")
      public StructuredWebserverLog.StructuredWebserverLogBuilder program(@NonNull String program) {
         if (program == null) {
            throw new NullPointerException("program is marked non-null but is null");
         }

         this.program = program;
         return this;
      }

      @JsonProperty("priority")
      @SuppressFBWarnings(justification = "generated code")
      public StructuredWebserverLog.StructuredWebserverLogBuilder level(@NonNull String level) {
         if (level == null) {
            throw new NullPointerException("level is marked non-null but is null");
         }

         this.level = level;
         return this;
      }

      @JsonProperty("sequence_number")
      @SuppressFBWarnings(justification = "generated code")
      public StructuredWebserverLog.StructuredWebserverLogBuilder sequenceNumber(long sequenceNumber) {
         this.sequenceNumber = sequenceNumber;
         return this;
      }

      @JsonProperty("thread")
      @SuppressFBWarnings(justification = "generated code")
      public StructuredWebserverLog.StructuredWebserverLogBuilder threadId(long threadId) {
         this.threadId = threadId;
         return this;
      }

      @JsonProperty("logger_name")
      @SuppressFBWarnings(justification = "generated code")
      public StructuredWebserverLog.StructuredWebserverLogBuilder loggerName(@Nullable String loggerName) {
         this.loggerName = loggerName;
         return this;
      }

      @JsonProperty("source_class")
      @SuppressFBWarnings(justification = "generated code")
      public StructuredWebserverLog.StructuredWebserverLogBuilder sourceClass(@Nullable String sourceClass) {
         this.sourceClass = sourceClass;
         return this;
      }

      @JsonProperty("source_method")
      @SuppressFBWarnings(justification = "generated code")
      public StructuredWebserverLog.StructuredWebserverLogBuilder sourceMethod(@Nullable String sourceMethod) {
         this.sourceMethod = sourceMethod;
         return this;
      }

      @JsonProperty("message")
      @SuppressFBWarnings(justification = "generated code")
      public StructuredWebserverLog.StructuredWebserverLogBuilder message(@Nullable String message) {
         this.message = message;
         return this;
      }

      @JsonProperty("exception")
      @SuppressFBWarnings(justification = "generated code")
      public StructuredWebserverLog.StructuredWebserverLogBuilder exception(@Nullable String exception) {
         this.exception = exception;
         return this;
      }

      @JsonProperty("label")
      @SuppressFBWarnings(justification = "generated code")
      public StructuredWebserverLog.StructuredWebserverLogBuilder label(@Nullable String label) {
         this.label = label;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public StructuredWebserverLog build() {
         return new StructuredWebserverLog(
            this.time,
            this.timestamp,
            this.program,
            this.level,
            this.sequenceNumber,
            this.threadId,
            this.loggerName,
            this.sourceClass,
            this.sourceMethod,
            this.message,
            this.exception,
            this.label
         );
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "StructuredWebserverLog.StructuredWebserverLogBuilder(time="
            + this.time
            + ", timestamp="
            + this.timestamp
            + ", program="
            + this.program
            + ", level="
            + this.level
            + ", sequenceNumber="
            + this.sequenceNumber
            + ", threadId="
            + this.threadId
            + ", loggerName="
            + this.loggerName
            + ", sourceClass="
            + this.sourceClass
            + ", sourceMethod="
            + this.sourceMethod
            + ", message="
            + this.message
            + ", exception="
            + this.exception
            + ", label="
            + this.label
            + ")";
      }
   }
}
