
package de.ivu.elect.business.datei.entity;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

import de.ivu.elect.business.exchange.entity.ImportStatus;


import static java.util.Arrays.asList;
import static java.util.Arrays.stream;
import static org.apache.commons.lang3.StringUtils.endsWithIgnoreCase;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.startsWithIgnoreCase;

public enum FileType {

  XML("application/xml", true, "xml"),
  CRT("application/x-x509-ca-cert", true, "crt"),
  PEM("application/x-pem-file", true, "pem"),
  P12("application/x-pkcs12", false, "p12"),
  CSV("text/csv", true, "csv"),
  ZIP("application/zip", true, "zip"),
  GZIP("application/gzip", false, "gz"),
  PDF("application/pdf", false, "pdf"),
  ODT("application/vnd.oasis.opendocument.text", false, "odt"),
  OTT("application/vnd.oasis.opendocument.text-template", false, "ott"),
  ODS("application/vnd.oasis.opendocument.spreadsheet", false, "ods"),
  DVZ(ZIP.getDefaultMimeType(), ZIP.isVorschauMoeglich(), "dvz"), // ELECT-5759
  DOCX("application/vnd.openxmlformats-officedocument.wordprocessingml.document", false, "docx"),
  DOC("application/msword", false, "doc"),
  XLS("application/vnd.ms-excel", false, "xls"),
  XLSX("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", false, "xlsx"),
  SQL("text/x-sql", false, "sql"),
  RTF("text/rtf", true, "rtf"),
  HTML("text/html", true, "html"),
  TXT("text/plain", true, "txt"),
  LAFST("text/plain", true, "lafst"),
  JPEG("image/jpeg", false, "jpg", "jpeg"),
  PNG("image/png", false, "png"),
  SVG("image/svg+xml", false, "svg"),
  EXE("application/vnd.microsoft.portable-executable", false, "exe"),
  JSON("application/json", false, "json"),
  ICS("text/calendar", false, "ics"),
  ALL("", false, "*");

  private final String defaultMimeType;

  private final boolean vorschauMoeglich;

  private final List<String> fileExtensions;

  FileType(String mimeType, boolean vorschauMoeglich, String fileExtension, String... fileExtensionAliases) {
    this.defaultMimeType = mimeType;

    this.vorschauMoeglich = vorschauMoeglich;

    this.fileExtensions = new ArrayList<>();
    this.fileExtensions.add(fileExtension);
    this.fileExtensions.addAll(asList(fileExtensionAliases));
  }

  public boolean isImage() {
    return startsWithIgnoreCase(getDefaultMimeType(), "image/");
  }

  public boolean isArchive() {
    return isZipFile() || this.equals(GZIP) || this.equals(DVZ);
  }

  public boolean isDokumentVorlageArchive() {
    return isZipFile() || this.equals(DVZ);
  }

  public boolean isPdfFile() {
    return this.equals(PDF);
  }

  public boolean isCsvFile() {
    return this.equals(CSV);
  }

  public boolean isXmlFile() {
    return this.equals(XML);
  }

  public boolean isZipFile() {
    return this.equals(ZIP);
  }

  public boolean isExeFile() {
    return this.equals(EXE);
  }

  public boolean isOpenDocumentFile() {
    return this.equals(ODT) || this.equals(ODS);
  }

  public String getDefaultMimeType() {
    return defaultMimeType;
  }

  public String getFileExtension() {
    return fileExtensions.iterator().next();
  }

  public List<String> getFileExtensions() {
    return fileExtensions;
  }

  /**
   * FIXME: Please refactor! (I'm with stupid...)
   * <p>
   * Es wird immer eine CsvDatei-Entität erstellt, da das Format später noch festgelegt werden kann.
   */
  public Datei createDatei() {
    return createCsvDatei();
  }

  public CsvDatei createCsvDatei() {
    return new CsvDatei();
  }

  public ImportStatus getDefaultUploadStatus() {
    return ImportStatus.HOCHGELADEN;
  }

  // ELECTMUC-290
  public boolean isVorschauMoeglich() {
    return vorschauMoeglich;
  }

  public static FileType fromFilename(String filename) {
    if (isBlank(filename)) {
      return ALL;
    }

    return stream(values()).filter(value -> value.fileExtensions.stream().anyMatch(fileExtension -> endsWithIgnoreCase(filename, fileExtension)))
        .max(Comparator.comparingInt(fileType -> fileType.getFileExtension().length())).orElse(ALL);
  }
}
