package com.airlock.iam.admin.application.service.maintenancemessage;

import com.airlock.iam.admin.api.domain.model.administrator.CurrentAdministrator;
import com.airlock.iam.admin.domain.model.maintenancemessage.MaintenanceMessage;
import com.airlock.iam.base.api.domain.model.exception.EntityNotFoundException;
import com.airlock.iam.base.api.domain.model.exception.EntityNotUniqueException;
import com.airlock.iam.base.api.domain.model.exception.FailureException;
import com.airlock.iam.base.api.domain.model.exception.ViolationException;
import com.airlock.iam.base.api.domain.model.validation.ValidationResult;
import com.airlock.iam.base.api.domain.model.validation.Validator;
import com.airlock.iam.base.misc.data.OptionalBoolean;
import com.airlock.iam.base.misc.data.OptionalString;
import com.airlock.iam.base.misc.data.OptionalValue;
import com.airlock.iam.base.misc.log.LogUtil;
import com.airlock.iam.common.api.domain.model.persistency.exception.NotFoundException;
import com.airlock.iam.common.api.domain.model.persistency.exception.NotUniqueException;
import com.airlock.iam.common.api.domain.model.persistency.exception.PersisterException;
import com.airlock.iam.core.misc.impl.sysmessage.MaintenanceMessageBean;
import com.airlock.iam.core.misc.sysmessage.MaintenanceMessagePersister;
import com.airlock.iam.log.api.signing.SigningLogger;
import com.google.common.collect.Maps;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.lang.reflect.InvocationTargetException;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import org.apache.commons.beanutils.PropertyUtils;

public class MaintenanceMessageService {
   public static final String MESSAGE_ID_PATTERN = "[a-zA-Z_0-9-]{3,25}";
   private final MaintenanceMessagePersister persister;
   private final Validator<MaintenanceMessage> createValidator;
   private final Validator<MaintenanceMessage> updateValidator;
   private final SigningLogger signingLogger;
   private final CurrentAdministrator admin;

   public List<MaintenanceMessage> retrieve(MaintenanceMessageService.RetrieveOptions options) {
      List<MaintenanceMessage> allMaintenanceMessages;
      try {
         allMaintenanceMessages = this.map(this.persister.getAllMaintenanceMessages());
      } catch (PersisterException e) {
         throw new FailureException("Error while retrieving maintenance messages.", e);
      }

      List<MaintenanceMessage> filteredMessages = allMaintenanceMessages.stream()
         .filter(mm -> this.filterExpired(options, mm))
         .filter(mm -> this.filterSystemAvailable(options, mm))
         .filter(mm -> this.filterActive(options, mm))
         .collect(Collectors.toList());
      if (options.getSortOption().isPresent()) {
         filteredMessages.sort(new MaintenanceMessageService.MaintenanceMessageComparator(options.getSortOption().get()));
      }

      return filteredMessages;
   }

   private boolean filterActive(MaintenanceMessageService.RetrieveOptions options, MaintenanceMessage mm) {
      return options.getFilterActive().isEmpty() || mm.isActive() == options.getFilterActive().get();
   }

   private boolean filterSystemAvailable(MaintenanceMessageService.RetrieveOptions options, MaintenanceMessage mm) {
      return options.getFilterSystemAvailable().isEmpty() || mm.isSystemAvailable() == options.getFilterSystemAvailable().get();
   }

   private boolean filterExpired(MaintenanceMessageService.RetrieveOptions options, MaintenanceMessage mm) {
      Optional<Boolean> expired = options.getFilterExpired();
      if (expired.isEmpty()) {
         return true;
      }

      boolean isValidNowOrInFuture = mm.isValidNow() || mm.isValidInFuture();
      return expired.get() != isValidNowOrInFuture;
   }

   public void create(MaintenanceMessage mm) {
      try {
         ValidationResult validationResult = this.validateCreate(mm);
         if (!validationResult.isValid()) {
            throw new ViolationException("The maintenance message is not valid: " + validationResult.getFailure());
         }

         this.persister.insertMaintenanceMessage(this.map(mm));
         this.signingLogger
            .log("Administrator %s created a maintenance message with name %s", new Object[]{LogUtil.quote(this.admin.getName()), LogUtil.quote(mm.getName())});
      } catch (NotUniqueException e) {
         throw new EntityNotUniqueException(e);
      } catch (PersisterException e) {
         throw new FailureException(e);
      }
   }

   public ValidationResult validateCreate(MaintenanceMessage mm) {
      return this.createValidator.validate(mm);
   }

   public ValidationResult validateUpdate(MaintenanceMessage mm) {
      return this.updateValidator.validate(mm);
   }

   public ValidationResult validate(MaintenanceMessageService.MaintenanceMessageUpdateParams params) {
      return this.updateValidator.validate(this.mergeUpdateParamsWithOldMessage(params));
   }

   public MaintenanceMessage get(String messageId) {
      try {
         return this.map(this.persister.getMaintenanceMessageByName(messageId));
      } catch (NotFoundException e) {
         throw new EntityNotFoundException(e);
      } catch (PersisterException e) {
         throw new FailureException(e);
      }
   }

   public Optional<MaintenanceMessage> find(String messageId) {
      try {
         return Optional.of(this.map(this.persister.getMaintenanceMessageByName(messageId)));
      } catch (NotFoundException e) {
         return Optional.empty();
      } catch (PersisterException e) {
         throw new FailureException(e);
      }
   }

   public void delete(String messageId) {
      MaintenanceMessage mm = this.get(messageId);

      try {
         this.persister.deleteMaintenanceMessage(this.map(mm));
         this.signingLogger
            .log("Administrator %s deleted the maintenance message with name %s", new Object[]{LogUtil.quote(this.admin.getName()), LogUtil.quote(messageId)});
      } catch (NotFoundException e) {
         throw new EntityNotFoundException(e);
      } catch (PersisterException e) {
         throw new FailureException(e);
      }
   }

   public MaintenanceMessage update(MaintenanceMessageService.MaintenanceMessageUpdateParams params) {
      MaintenanceMessage newMm = this.mergeUpdateParamsWithOldMessage(params);
      ValidationResult validationResult = this.validateUpdate(newMm);
      if (!validationResult.isValid()) {
         throw new ViolationException("The maintenance message is not valid: " + validationResult.getFailure());
      }

      try {
         this.persister.updateMaintenanceMessage(this.map(newMm));
         this.signingLogger
            .log(
               "Administrator %s updated the maintenance message with name %s",
               new Object[]{LogUtil.quote(this.admin.getName()), LogUtil.quote(newMm.getName())}
            );
         return newMm;
      } catch (NotFoundException e) {
         throw new EntityNotFoundException(e);
      } catch (PersisterException e) {
         throw new FailureException(e);
      }
   }

   private MaintenanceMessage mergeUpdateParamsWithOldMessage(MaintenanceMessageService.MaintenanceMessageUpdateParams params) {
      MaintenanceMessage oldMm = this.get(params.getMmId());
      Map<String, String> newTranslations = Maps.newHashMap(oldMm.getTranslations());
      if (params.getTranslations().hasValue()) {
         newTranslations.putAll((Map<? extends String, ? extends String>)params.getTranslations().value());
      }

      newTranslations = newTranslations.entrySet().stream().filter(e -> e.getValue() != null).collect(Collectors.toMap(Entry::getKey, Entry::getValue));
      return MaintenanceMessage.builder()
         .name(oldMm.getName())
         .active((Boolean)params.getActive().orElse(oldMm.isActive()))
         .location(Optional.ofNullable((String)params.getLocation().orElse(oldMm.getLocation().orElse(null))))
         .systemAvailable((Boolean)params.getSystemAvailable().orElse(oldMm.isSystemAvailable()))
         .validFrom((Date)params.getValidFrom().orElse(oldMm.getValidFrom()))
         .validTo((Date)params.getValidTo().orElse(oldMm.getValidTo()))
         .translations(newTranslations)
         .build();
   }

   private MaintenanceMessage map(com.airlock.iam.core.misc.sysmessage.MaintenanceMessage message) {
      return MaintenanceMessage.builder()
         .name(message.getName())
         .active(message.isActive())
         .location(Optional.ofNullable(message.getLocation()))
         .systemAvailable(message.isSystemAvailable())
         .validFrom(message.getValidFrom())
         .validTo(message.getValidTo())
         .translations(message.getLanguages().stream().collect(Collectors.toMap(lang -> (String)lang, lang -> message.getMessage(lang))))
         .build();
   }

   private List<MaintenanceMessage> map(List<com.airlock.iam.core.misc.sysmessage.MaintenanceMessage> messages) {
      return messages.stream().map(message -> this.map(message)).collect(Collectors.toList());
   }

   private com.airlock.iam.core.misc.sysmessage.MaintenanceMessage map(MaintenanceMessage message) {
      MaintenanceMessageBean mmBean = new MaintenanceMessageBean(
         message.getName(), message.isSystemAvailable(), message.isActive(), message.getValidFrom(), message.getValidTo(), message.getLocation().orElse(null)
      );
      mmBean.setTranslations(message.getTranslations());
      return mmBean;
   }

   @SuppressFBWarnings(justification = "generated code")
   MaintenanceMessageService(
      MaintenanceMessagePersister persister,
      Validator<MaintenanceMessage> createValidator,
      Validator<MaintenanceMessage> updateValidator,
      SigningLogger signingLogger,
      CurrentAdministrator admin
   ) {
      this.persister = persister;
      this.createValidator = createValidator;
      this.updateValidator = updateValidator;
      this.signingLogger = signingLogger;
      this.admin = admin;
   }

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

   private record MaintenanceMessageComparator(MaintenanceMessageService.SortOption sortOption) implements Comparator<MaintenanceMessage> {
      public int compare(MaintenanceMessage m1, MaintenanceMessage m2) {
         Date date1;
         Date date2;
         try {
            date1 = (Date)PropertyUtils.getProperty(m1, this.sortOption.getAttribute());
            date2 = (Date)PropertyUtils.getProperty(m2, this.sortOption.getAttribute());
         } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
            throw new IllegalArgumentException(e);
         }

         return this.sortOption.isAscending() ? date1.compareTo(date2) : date2.compareTo(date1);
      }
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class MaintenanceMessageServiceBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private MaintenanceMessagePersister persister;
      @SuppressFBWarnings(justification = "generated code")
      private Validator<MaintenanceMessage> createValidator;
      @SuppressFBWarnings(justification = "generated code")
      private Validator<MaintenanceMessage> updateValidator;
      @SuppressFBWarnings(justification = "generated code")
      private SigningLogger signingLogger;
      @SuppressFBWarnings(justification = "generated code")
      private CurrentAdministrator admin;

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

      @SuppressFBWarnings(justification = "generated code")
      public MaintenanceMessageService.MaintenanceMessageServiceBuilder persister(MaintenanceMessagePersister persister) {
         this.persister = persister;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public MaintenanceMessageService.MaintenanceMessageServiceBuilder createValidator(Validator<MaintenanceMessage> createValidator) {
         this.createValidator = createValidator;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public MaintenanceMessageService.MaintenanceMessageServiceBuilder updateValidator(Validator<MaintenanceMessage> updateValidator) {
         this.updateValidator = updateValidator;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public MaintenanceMessageService.MaintenanceMessageServiceBuilder signingLogger(SigningLogger signingLogger) {
         this.signingLogger = signingLogger;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public MaintenanceMessageService.MaintenanceMessageServiceBuilder admin(CurrentAdministrator admin) {
         this.admin = admin;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public MaintenanceMessageService build() {
         return new MaintenanceMessageService(this.persister, this.createValidator, this.updateValidator, this.signingLogger, this.admin);
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "MaintenanceMessageService.MaintenanceMessageServiceBuilder(persister="
            + this.persister
            + ", createValidator="
            + this.createValidator
            + ", updateValidator="
            + this.updateValidator
            + ", signingLogger="
            + this.signingLogger
            + ", admin="
            + this.admin
            + ")";
      }
   }

   public static final class MaintenanceMessageUpdateParams {
      private final String mmId;
      private final OptionalString location;
      private final OptionalBoolean active;
      private final OptionalValue<Date> validFrom;
      private final OptionalValue<Date> validTo;
      private final OptionalValue<Map<String, String>> translations;
      private final OptionalBoolean systemAvailable;

      private MaintenanceMessageUpdateParams() {
         this.mmId = null;
         this.location = OptionalString.none();
         this.active = OptionalBoolean.none();
         this.validFrom = OptionalValue.none();
         this.validTo = OptionalValue.none();
         this.translations = OptionalValue.none();
         this.systemAvailable = OptionalBoolean.none();
      }

      public static MaintenanceMessageService.MaintenanceMessageUpdateParams.MaintenanceMessageUpdateParamsBuilder builder() {
         return new MaintenanceMessageService.MaintenanceMessageUpdateParams().toBuilder();
      }

      @SuppressFBWarnings(justification = "generated code")
      public MaintenanceMessageService.MaintenanceMessageUpdateParams.MaintenanceMessageUpdateParamsBuilder toBuilder() {
         return new MaintenanceMessageService.MaintenanceMessageUpdateParams.MaintenanceMessageUpdateParamsBuilder()
            .mmId(this.mmId)
            .location(this.location)
            .active(this.active)
            .validFrom(this.validFrom)
            .validTo(this.validTo)
            .translations(this.translations)
            .systemAvailable(this.systemAvailable);
      }

      @SuppressFBWarnings(justification = "generated code")
      public String getMmId() {
         return this.mmId;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OptionalString getLocation() {
         return this.location;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OptionalBoolean getActive() {
         return this.active;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OptionalValue<Date> getValidFrom() {
         return this.validFrom;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OptionalValue<Date> getValidTo() {
         return this.validTo;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OptionalValue<Map<String, String>> getTranslations() {
         return this.translations;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OptionalBoolean getSystemAvailable() {
         return this.systemAvailable;
      }

      @SuppressFBWarnings(justification = "generated code")
      public MaintenanceMessageUpdateParams(
         String mmId,
         OptionalString location,
         OptionalBoolean active,
         OptionalValue<Date> validFrom,
         OptionalValue<Date> validTo,
         OptionalValue<Map<String, String>> translations,
         OptionalBoolean systemAvailable
      ) {
         this.mmId = mmId;
         this.location = location;
         this.active = active;
         this.validFrom = validFrom;
         this.validTo = validTo;
         this.translations = translations;
         this.systemAvailable = systemAvailable;
      }

      @SuppressFBWarnings(justification = "generated code")
      public static class MaintenanceMessageUpdateParamsBuilder {
         @SuppressFBWarnings(justification = "generated code")
         private String mmId;
         @SuppressFBWarnings(justification = "generated code")
         private OptionalString location;
         @SuppressFBWarnings(justification = "generated code")
         private OptionalBoolean active;
         @SuppressFBWarnings(justification = "generated code")
         private OptionalValue<Date> validFrom;
         @SuppressFBWarnings(justification = "generated code")
         private OptionalValue<Date> validTo;
         @SuppressFBWarnings(justification = "generated code")
         private OptionalValue<Map<String, String>> translations;
         @SuppressFBWarnings(justification = "generated code")
         private OptionalBoolean systemAvailable;

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

         @SuppressFBWarnings(justification = "generated code")
         public MaintenanceMessageService.MaintenanceMessageUpdateParams.MaintenanceMessageUpdateParamsBuilder mmId(String mmId) {
            this.mmId = mmId;
            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public MaintenanceMessageService.MaintenanceMessageUpdateParams.MaintenanceMessageUpdateParamsBuilder location(OptionalString location) {
            this.location = location;
            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public MaintenanceMessageService.MaintenanceMessageUpdateParams.MaintenanceMessageUpdateParamsBuilder active(OptionalBoolean active) {
            this.active = active;
            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public MaintenanceMessageService.MaintenanceMessageUpdateParams.MaintenanceMessageUpdateParamsBuilder validFrom(OptionalValue<Date> validFrom) {
            this.validFrom = validFrom;
            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public MaintenanceMessageService.MaintenanceMessageUpdateParams.MaintenanceMessageUpdateParamsBuilder validTo(OptionalValue<Date> validTo) {
            this.validTo = validTo;
            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public MaintenanceMessageService.MaintenanceMessageUpdateParams.MaintenanceMessageUpdateParamsBuilder translations(
            OptionalValue<Map<String, String>> translations
         ) {
            this.translations = translations;
            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public MaintenanceMessageService.MaintenanceMessageUpdateParams.MaintenanceMessageUpdateParamsBuilder systemAvailable(OptionalBoolean systemAvailable) {
            this.systemAvailable = systemAvailable;
            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public MaintenanceMessageService.MaintenanceMessageUpdateParams build() {
            return new MaintenanceMessageService.MaintenanceMessageUpdateParams(
               this.mmId, this.location, this.active, this.validFrom, this.validTo, this.translations, this.systemAvailable
            );
         }

         @SuppressFBWarnings(justification = "generated code")
         @Override
         public String toString() {
            return "MaintenanceMessageService.MaintenanceMessageUpdateParams.MaintenanceMessageUpdateParamsBuilder(mmId="
               + this.mmId
               + ", location="
               + this.location
               + ", active="
               + this.active
               + ", validFrom="
               + this.validFrom
               + ", validTo="
               + this.validTo
               + ", translations="
               + this.translations
               + ", systemAvailable="
               + this.systemAvailable
               + ")";
         }
      }
   }

   public static final class RetrieveOptions {
      private final Optional<Boolean> filterExpired;
      private final Optional<Boolean> filterSystemAvailable;
      private final Optional<Boolean> filterActive;
      private final Optional<MaintenanceMessageService.SortOption> sortOption;

      private RetrieveOptions() {
         this.filterExpired = Optional.empty();
         this.filterSystemAvailable = Optional.empty();
         this.filterActive = Optional.empty();
         this.sortOption = Optional.empty();
      }

      public static MaintenanceMessageService.RetrieveOptions.RetrieveOptionsBuilder builder() {
         return new MaintenanceMessageService.RetrieveOptions().toBuilder();
      }

      public static MaintenanceMessageService.RetrieveOptions empty() {
         return builder().build();
      }

      @SuppressFBWarnings(justification = "generated code")
      public MaintenanceMessageService.RetrieveOptions.RetrieveOptionsBuilder toBuilder() {
         return new MaintenanceMessageService.RetrieveOptions.RetrieveOptionsBuilder()
            .filterExpired(this.filterExpired)
            .filterSystemAvailable(this.filterSystemAvailable)
            .filterActive(this.filterActive)
            .sortOption(this.sortOption);
      }

      @SuppressFBWarnings(justification = "generated code")
      public Optional<Boolean> getFilterExpired() {
         return this.filterExpired;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Optional<Boolean> getFilterSystemAvailable() {
         return this.filterSystemAvailable;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Optional<Boolean> getFilterActive() {
         return this.filterActive;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Optional<MaintenanceMessageService.SortOption> getSortOption() {
         return this.sortOption;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RetrieveOptions(
         Optional<Boolean> filterExpired,
         Optional<Boolean> filterSystemAvailable,
         Optional<Boolean> filterActive,
         Optional<MaintenanceMessageService.SortOption> sortOption
      ) {
         this.filterExpired = filterExpired;
         this.filterSystemAvailable = filterSystemAvailable;
         this.filterActive = filterActive;
         this.sortOption = sortOption;
      }

      @SuppressFBWarnings(justification = "generated code")
      public static class RetrieveOptionsBuilder {
         @SuppressFBWarnings(justification = "generated code")
         private Optional<Boolean> filterExpired;
         @SuppressFBWarnings(justification = "generated code")
         private Optional<Boolean> filterSystemAvailable;
         @SuppressFBWarnings(justification = "generated code")
         private Optional<Boolean> filterActive;
         @SuppressFBWarnings(justification = "generated code")
         private Optional<MaintenanceMessageService.SortOption> sortOption;

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

         @SuppressFBWarnings(justification = "generated code")
         public MaintenanceMessageService.RetrieveOptions.RetrieveOptionsBuilder filterExpired(Optional<Boolean> filterExpired) {
            this.filterExpired = filterExpired;
            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public MaintenanceMessageService.RetrieveOptions.RetrieveOptionsBuilder filterSystemAvailable(Optional<Boolean> filterSystemAvailable) {
            this.filterSystemAvailable = filterSystemAvailable;
            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public MaintenanceMessageService.RetrieveOptions.RetrieveOptionsBuilder filterActive(Optional<Boolean> filterActive) {
            this.filterActive = filterActive;
            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public MaintenanceMessageService.RetrieveOptions.RetrieveOptionsBuilder sortOption(Optional<MaintenanceMessageService.SortOption> sortOption) {
            this.sortOption = sortOption;
            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public MaintenanceMessageService.RetrieveOptions build() {
            return new MaintenanceMessageService.RetrieveOptions(this.filterExpired, this.filterSystemAvailable, this.filterActive, this.sortOption);
         }

         @SuppressFBWarnings(justification = "generated code")
         @Override
         public String toString() {
            return "MaintenanceMessageService.RetrieveOptions.RetrieveOptionsBuilder(filterExpired="
               + this.filterExpired
               + ", filterSystemAvailable="
               + this.filterSystemAvailable
               + ", filterActive="
               + this.filterActive
               + ", sortOption="
               + this.sortOption
               + ")";
         }
      }
   }

   public static final class SortOption {
      private final boolean ascending;
      private final String attribute;

      @SuppressFBWarnings(justification = "generated code")
      public boolean isAscending() {
         return this.ascending;
      }

      @SuppressFBWarnings(justification = "generated code")
      public String getAttribute() {
         return this.attribute;
      }

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

            Object this$attribute = this.attribute;
            Object other$attribute = other.attribute;
            return this$attribute == null ? other$attribute == null : this$attribute.equals(other$attribute);
         }
      }

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

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "MaintenanceMessageService.SortOption(ascending=" + this.isAscending() + ", attribute=" + this.getAttribute() + ")";
      }

      @SuppressFBWarnings(justification = "generated code")
      public SortOption(boolean ascending, String attribute) {
         this.ascending = ascending;
         this.attribute = attribute;
      }
   }
}
