
package de.ivu.elect.presentation.exchange;

import static org.apache.commons.lang3.StringUtils.isNotBlank;

import java.io.File;
import java.io.FileInputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipInputStream;

import javax.inject.Inject;
import javax.inject.Named;

import org.apache.deltaspike.core.api.scope.ViewAccessScoped;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.ivu.elect.business.datei.control.DateiLeser;
import de.ivu.elect.business.datei.entity.Datei;
import de.ivu.elect.business.datei.entity.DateiConstants;
import de.ivu.elect.business.datei.entity.FileType;
import de.ivu.elect.business.konfiguration.control.AbstractStreamCreator;
import de.ivu.elect.business.konfiguration.control.StreamCreator;
import de.ivu.elect.business.security.UseCasePermission;
import de.ivu.elect.jee.presentation.dynamicform.AdvancedDynaFormModel;
import de.ivu.elect.jee.presentation.dynamicform.DynamicFormEditOrCreateView;
import de.ivu.elect.jee.presentation.dynamicform.FormBuilder;
import de.ivu.elect.jee.presentation.dynamicform.ReadOnlyStringProperty;
import de.ivu.elect.jee.presentation.redirect.Redirect;
import de.ivu.elect.jee.presentation.view.AbstractView;
import de.ivu.elect.presentation.View;
import de.ivu.elect.presentation.hilfe.OnlineHilfeId;

@OnlineHilfeId(value = "148", mehrfachVergebenOk = true)
@Named(DateiAnzeigenView.COMPONENT_NAME)
@ViewAccessScoped
@View(viewId = DateiAnzeigenView.VIEW_ID, useCase = UseCasePermission.OHNE)
public class DateiAnzeigenView extends AbstractView implements DynamicFormEditOrCreateView {

  private static final long serialVersionUID = 1L;

  public static final String COMPONENT_NAME = "dateiAnzeigenView";

  public static final String VIEW_ID = "/exchange/datei-anzeigen.xhtml";

  private static final Logger LOG = LoggerFactory.getLogger(DateiVorschauView.class);

  private static final Charset FILE_ENCODING = StandardCharsets.UTF_8;

  @Inject
  private transient DateiLeser dateiLeser;

  private String filePathName;

  public DateiAnzeigenView() {
    super();
  }

  @Redirect
  public String init(String filePathName) {
    this.filePathName = filePathName;

    return VIEW_ID;
  }

  @Override
  public AdvancedDynaFormModel getModel() {
    FormBuilder formBuilder = new FormBuilder();

    formBuilder.addProperty(new ReadOnlyStringProperty(getMessage(DateiConstants.MESSAGE_KEY_ENTITY_EINZAHL), filePathName));

    if (!isDateiVorhanden()) {
      formBuilder.addProperty(new ReadOnlyStringProperty(getMessage("datei.anzeigen.datei.exists.label"), getMessage("datei.anzeigen.datei.exists.value.false")));
    }

    return formBuilder.createModel();
  }

  private boolean isDateiVorhanden() {
    return isNotBlank(filePathName) && new File(filePathName).isFile();
  }

  // Hier wird bereits die Seite gerendert, es sollte also nicht knallen -> CATCH-Alles
  public List<String> getLines() {
    if (!isDateiVorhanden()) {
      return new ArrayList<>();
    }

    Datei datei = new Datei();
    datei.setDateiname(filePathName);

    if (isZipFile()) {
      datei.setFileType(FileType.ZIP);
    }

    try {
      return dateiLeser.liesDatenAusDatei(createStreamCreator(), datei, FILE_ENCODING);
    } catch (Exception ex) {
      addErrorMessage(ex);

      LOG.warn(ex.getLocalizedMessage(), ex);

      return new ArrayList<>();
    }
  }

  private StreamCreator createStreamCreator() {
    return new AbstractStreamCreator() {

      private static final long serialVersionUID = 1L;

      @Override
      protected String getAbsolutePath(String dateiname, String path) {
        return dateiname;
      }
    };
  }

  private boolean isZipFile() {
    if (!isDateiVorhanden()) {
      return false;
    }

    try (ZipInputStream zis = new ZipInputStream(new FileInputStream(filePathName))) {
      // nur versuchen
      return zis.getNextEntry() != null;
    } catch (Exception e) {
      return false;
    }
  }

  @Override
  public String getBtnSaveLabel() {
    return null;
  }

  @Override
  public boolean isBtnSaveRendered() {
    return false;
  }

  @Redirect
  @Override
  public String save() {
    return null;
  }

  @Override
  public boolean isBtnResetRendered() {
    return false;
  }

  @Redirect
  @Override
  public String reset() {
    return null;
  }

  @Override
  public boolean isBtnCancelRendered() {
    return true;
  }

  @Redirect
  @Override
  public String cancel() {
    return goBack();
  }
}
