
package de.ivu.elect.presentation.kandidatur.action;

import static de.ivu.elect.jee.entity.EntityUtil.castTo;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Inject;

import de.ivu.elect.business.kandidatur.boundary.ErsatzkandidaturChangeEvent;
import de.ivu.elect.business.kandidatur.boundary.ErsatzkandidaturExtendedDAO;
import de.ivu.elect.business.kandidatur.entity.Ersatzkandidatur;
import de.ivu.elect.business.kandidatur.entity.Kandidatur;

public abstract class AbstractErsatzkandidaturAction extends AbstractKandidaturAction {

  private static final long serialVersionUID = 1L;

  @Inject
  private transient ErsatzkandidaturExtendedDAO ersatzkandidaturExtendedDAO;

  @Inject
  private transient ErsatzkandidaturChangeEvent ersatzkandidaturChangeEvent;

  protected AbstractErsatzkandidaturAction() {
    super();
  }

  @Override
  public boolean isDisabledInternal(@Nonnull Kandidatur kandidatur) {
    return super.isDisabledInternal(kandidatur) || !isErsatzkandidatur(kandidatur) || isDisabledInternal(asErsatzkandidatur(kandidatur));
  }

  protected abstract boolean isDisabledInternal(Ersatzkandidatur ersatzkandidatur);

  @Override
  public String doIt(Kandidatur kandidatur) {
    if (isErsatzkandidatur(kandidatur)) {
      Ersatzkandidatur ersatzkandidatur = asErsatzkandidatur(kandidatur);

      if (ersatzkandidatur != null) {
        return doIt(ersatzkandidatur);
      }
    }

    throw new UnsupportedOperationException("Das Bearbeiten der uebergebenen Kandidatur [kandidatur = <" + kandidatur + ">] wird nicht unterstuetzt");
  }

  protected abstract String doIt(@Nonnull Ersatzkandidatur ersatzkandidatur);

  @Override
  protected void fireChangeEvent() {
    ersatzkandidaturChangeEvent.sendChangeEvent();
  }

  @Override
  protected Kandidatur attach(Kandidatur kandidatur) {
    if (isErsatzkandidatur(kandidatur)) {
      return asErsatzkandidatur(kandidatur);
    }

    return super.attach(kandidatur);
  }

  private boolean isErsatzkandidatur(Kandidatur kandidatur) {
    return kandidatur != null && kandidatur.isInstanceOf(Ersatzkandidatur.class);
  }

  @Nullable
  protected Ersatzkandidatur asErsatzkandidatur(Kandidatur kandidatur) {
    if (isErsatzkandidatur(kandidatur)) {
      return ersatzkandidaturExtendedDAO.attach(castTo(kandidatur, Ersatzkandidatur.class)); // ELECT-11075
    }

    return null;
  }
}
