package com.oguerreiro.resilient.activities.period.reopen;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;

import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.oguerreiro.resilient.activity.AbstractActivity;
import com.oguerreiro.resilient.activity.GenericGuide;
import com.oguerreiro.resilient.activity.GenericResult;
import com.oguerreiro.resilient.activity.WorkResultEnum;
import com.oguerreiro.resilient.activity.registry.ActivityProgressRegistry;
import com.oguerreiro.resilient.domain.Period;
import com.oguerreiro.resilient.domain.enumeration.PeriodStatus;
import com.oguerreiro.resilient.repository.PeriodRepository;

@Component
public class PeriodReopenActivityImpl extends
    AbstractActivity<GenericResult, GenericGuide<Period>, PeriodReopenActivity> implements PeriodReopenActivity {

  private static final String ACTIVITY_KEY = "period-reopen";

  private final PeriodRepository periodRepository;
  private final ActivityProgressRegistry activityProgressRegistry;

  /* ----- Constructor ----- */
  public PeriodReopenActivityImpl(PeriodRepository periodRepository,
      ActivityProgressRegistry activityProgressRegistry) {
    this.periodRepository = periodRepository;
    this.activityProgressRegistry = activityProgressRegistry;
  }

  /* ----- SelectionStrategy properties ----- */
  @Override
  public Class appliesToActivityDomainClass() {
    return Period.class;
  }

  @Override
  public List<String> appliesToStates() {
    return Arrays.asList(PeriodStatus.CLOSED.toString(), PeriodStatus.ENDED.toString());
  }

  /* ----- Activity implementation ----- */
  @Override
  public String getActivityKey() {
    return ACTIVITY_KEY;
  }

  @Transactional(propagation = Propagation.REQUIRES_NEW)
  @Override
  public GenericResult doActivity(String activityDomainClass, Long activityDomainId) {
    // Load Period
    Period period = periodRepository.getReferenceById(activityDomainId);

    // Validations
    if (!period.getState().equals(PeriodStatus.CLOSED) && !period.getState().equals(PeriodStatus.ENDED)) {
      throw new RuntimeException("Activity Close, applies only to Opened period state.");
    }

    // Change status
    period.setState(PeriodStatus.OPENED);

    // Return without waiting
    return new GenericResult(WorkResultEnum.COMPLETED);
  }

  @Override
  public CompletableFuture<GenericResult> doInternalActivityAsync(GenericGuide<Period> guide) {
    // TODO Auto-generated method stub
    return null;
  }
}
