package com.airlock.iam.servicecontainer.app.application.configuration.task;

import com.airlock.iam.base.misc.concurrent.ThreadUtils;
import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.elog.api.ELoggerFactory;
import com.airlock.iam.elog.api.LogTypes;
import com.airlock.iam.plugin.api.annotation.config.Plugin;
import com.airlock.iam.plugin.api.annotation.property.LongProperty;
import com.airlock.iam.servicecontainer.api.application.configuration.task.TaskConfig;
import com.airlock.iam.servicecontainer.api.domain.model.task.AbstractTask;
import com.airlock.iam.servicecontainer.api.domain.model.task.Task;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.concurrent.TimeUnit;

@Plugin(description = "Task for testing.<p>Task counting from 1 to 100 in about 30 seconds. The task logs the counter to the log file on error level.</p>")
public class TestTask extends AbstractTask implements TaskConfig {
   private static final ELogger LOG = ELoggerFactory.getLogger(TestTask.class);
   private static final long DEFAULT_SLEEP_MILLIS = 300L;
   private static final long REFERENCE_SLEEP_MILLIS = 1000L;
   private static final long EXAMPLE_SLEEP_MILLIS = 2000L;
   @LongProperty(
      description = "Number of milliseconds between each written log statement.",
      optional = true,
      minValue = 0L,
      maxValue = Long.MAX_VALUE,
      exampleValues = {300L, 1000L, 2000L},
      defaultValue = 300L
   )
   private Long sleepMillis;

   @Override
   public void executeInternal() {
      while (this.getProgressPercentage() < 100) {
         this.setProgressPercentage(this.getProgressPercentage() + 1);
         LOG.info(LogTypes.SERVER_INFO_SYS, "TestTask completion: " + this.getProgressPercentage() + "%");
         ThreadUtils.sleepInterruptibly(this.sleepMillis, TimeUnit.MILLISECONDS);
         if (this.checkShouldStop()) {
            LOG.info(LogTypes.SERVER_INFO_SYS, "TestTask has been asked to stop.");
            break;
         }
      }
   }

   @Override
   public Task getLogic() {
      return this;
   }

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

   @SuppressFBWarnings(justification = "generated code")
   public TestTask() {
   }

   @SuppressFBWarnings(justification = "generated code")
   public TestTask(Long sleepMillis) {
      this.sleepMillis = sleepMillis;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class TestTaskBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private Long sleepMillis;

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

      @SuppressFBWarnings(justification = "generated code")
      public TestTask.TestTaskBuilder sleepMillis(Long sleepMillis) {
         this.sleepMillis = sleepMillis;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public TestTask build() {
         return new TestTask(this.sleepMillis);
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "TestTask.TestTaskBuilder(sleepMillis=" + this.sleepMillis + ")";
      }
   }
}
