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

import com.airlock.iam.core.misc.plugin.config.activation.ActivationState;
import com.airlock.iam.core.misc.plugin.config.activation.FileConfigActivationMessenger;
import com.airlock.iam.plugin.framework.misc.AppId;
import java.nio.file.Path;
import java.time.Duration;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public interface ActivationStateWatcher {
   static ActivationStateWatcher activationStateWatcher(Optional<Path> activationStatesDir, Duration deployTimeoutInMs) {
      if (activationStatesDir.isEmpty()) {
         return new NullActivationStateWatcher();
      }

      Collection<ActivationState> deletedActivationStates = FileConfigActivationMessenger.deleteActivationStates(activationStatesDir.get());
      List<AppId> previousApps = statesToAppIds(deletedActivationStates);
      return new FileBasedActivationStateWatcher(activationStatesDir.get(), previousApps, Duration.ofMillis(100L), deployTimeoutInMs);
   }

   ActivationStateWatcher.DeploymentResult waitForDeploymentResult();

   List<ActivationState> getActivationStates();

   void startActivation();

   boolean isOngoing();

   static List<AppId> statesToAppIds(Collection<ActivationState> states) {
      return states.stream().<AppId>map(ActivationState::getApplicationId).collect(Collectors.toList());
   }

   enum ActivationResult {
      SUCCESS,
      FAILED,
      TIMEOUT,
      NO_ACTIVATION_STATES;
   }

   record DeploymentResult(ActivationStateWatcher.ActivationResult activationResult, List<ActivationState> activationStates) {
   }
}
