
package de.ivu.elect.core.exchange.wahl;

import static java.util.stream.Collectors.toList;

import java.io.OutputStream;
import java.util.List;

import javax.inject.Inject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.ivu.elect.business.CurrentCustomer;
import de.ivu.elect.business.datei.entity.FileType;
import de.ivu.elect.business.exchange.control.FileFormat;
import de.ivu.elect.business.exchange.control.FileKonfiguration;
import de.ivu.elect.business.exchange.control.MappingException;
import de.ivu.elect.business.gebietsbaum.boundary.GebietDAO;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.security.Customer;
import de.ivu.elect.business.wahl.boundary.WahlDAO;
import de.ivu.elect.business.wahl.control.AbstractNlExportArtefaktNachSystemExportstatusExportContext;
import de.ivu.elect.business.wahl.control.NlExportArtefaktNachSystemExportstatusExportObject;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.jee.faces.Messages;
import de.ivu.elect.util.FileUtil;

public abstract class AbstractNlExportArtefaktNachSystemExportstatusExportMapper implements NlExportArtefaktNachSystemExportstatusExportMapper {

  @Inject
  private transient WahlDAO wahlDAO;

  @Inject
  private transient GebietDAO gebietDAO;

  @Inject
  private transient CurrentCustomer currentCustomer;

  @Inject
  private transient Messages messages;

  private final Logger log;

  protected AbstractNlExportArtefaktNachSystemExportstatusExportMapper() {
    super();

    this.log = LoggerFactory.getLogger(getClass());
  }

  @Override
  public boolean supportsBulkExportNachSystemExportstatus(AbstractNlExportArtefaktNachSystemExportstatusExportContext context) {
    return !context.isKorrekturenStimmeingabenExported();
  }

  protected String createTargetFileName(AbstractNlExportArtefaktNachSystemExportstatusExportContext context, FileFormat fileFormat, FileType fileType) {
    return createTargetFileName(context, createTargetSimpleFileName(fileFormat), fileType);
  }

  protected String createTargetFileName(AbstractNlExportArtefaktNachSystemExportstatusExportContext context, String simpleFileName, FileType fileType) {
    return FileUtil.normalizeZipEntryNamePreserveCase(simpleFileName) + "." + fileType.getFileExtension();
  }

  protected String createTargetSimpleFileName(FileFormat fileFormat) {
    return getMessage(fileFormat.getName());
  }

  protected String createTargetSimpleFileName(String fileNamePrefix, Wahl wahl, Gebiet gebiet) {
    return fileNamePrefix + "_" + wahl.getKennzeichen() + "_" + gebiet.getName();
  }

  @Override
  public void serialize(NlExportArtefaktNachSystemExportstatusExportObject exportObject, OutputStream os, AbstractNlExportArtefaktNachSystemExportstatusExportContext context,
      FileKonfiguration fileKonfiguration) throws MappingException {
    try {
      serialize(exportObject, os, context, fileKonfiguration, true);
    } catch (Exception ex) {
      throw new MappingException(ex.getMessage(), ex);
    }
  }

  protected Wahl attachWahl(AbstractNlExportArtefaktNachSystemExportstatusExportContext context) {
    return getWahlDAO().attach(context.getWahl());
  }

  protected final Gebiet attachWurzelgebiet(AbstractNlExportArtefaktNachSystemExportstatusExportContext context) {
    return context.getWurzelgebiet(getGebietDAO());
  }

  protected List<Gebiet> attachListenwahlgebiete(AbstractNlExportArtefaktNachSystemExportstatusExportContext context) {
    return attachWurzelgebiet(context).getUntergeordneteGebieteSortiertNachPosition(getGebietDAO()).stream() //
        .filter(Gebiet::isListenwahlgebiet) //
        .collect(toList());
  }

  protected WahlDAO getWahlDAO() {
    return wahlDAO;
  }

  protected GebietDAO getGebietDAO() {
    return gebietDAO;
  }

  protected Customer getCustomer() {
    return currentCustomer.getCustomer();
  }

  protected String getMessage(String msgKey, Object... params) {
    return getMessages().getMessageForMessageKey(msgKey, params);
  }

  protected String getMessage(Enum< ? > enumValue, Object... params) {
    return getMessages().lokalisiere(enumValue, params);
  }

  protected Messages getMessages() {
    return messages;
  }

  protected void info(String format, Object... params) {
    log.info(format, params);
  }

  protected void warn(String format, Throwable cause) {
    log.warn(format, cause);
  }

  protected void warn(String format, Object... params) {
    log.warn(format, params);
  }

  protected void error(String format, Object... params) {
    log.error(format, params);
  }

  protected void error(String format, Throwable cause) {
    log.error(format, cause);
  }
}
