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

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

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import org.apache.commons.io.ByteOrderMark;

import de.ivu.elect.jee.startup.StartupBootstrap;

public enum CsvZeichensatz {

  UTF_8("UTF-8"),
  UTF_8_BOM("UTF-8", ByteOrderMark.UTF_8), // NOTE: Schreibt Information an Anfang der Datei -> bei zusammengesetzten Exporten nur einmal verwenden!
  UTF_16("UTF-16" /* , ByteOrderMark.UTF_16LE, ByteOrderMark.UTF_16LE */),
  ISO_8859_1("ISO-8859-1"),
  ISO_8859_15("ISO-8859-15"),
  WINDOWS_1252("windows-1252"),
  US_ASCII("US-ASCII");

  private final String charsetName;

  private final Optional<ByteOrderMark> charsetBom;

  private CsvZeichensatz(String charsetName) {
    this(charsetName, null);
  }

  private CsvZeichensatz(String charsetName, ByteOrderMark charsetBom) {
    this.charsetName = charsetName;
    this.charsetBom = Optional.ofNullable(charsetBom);
  }

  public String getZeichensatz() {
    return getCharsetName();
  }

  public String getCharsetName() {
    return charsetName;
  }

  public Optional<ByteOrderMark> getCharsetBom() {
    boolean charsetBomUsageEnabledAnyway = this.equals(UTF_8_BOM);

    // NOTE ELECT-5818, dass dieses Feature momentan DEAKTIVIERT ist, da es (noch) nicht allgemeingültig ist!
    if (charsetBomUsageEnabledAnyway || "true".equalsIgnoreCase(System.getProperty(StartupBootstrap.DEFAULT_CHARSET_BOM_USAGE_ENABLED))) {
      if (this.equals(UTF_8)) {
        return UTF_8_BOM.getCharsetBom();
      }

      return charsetBom;
    }

    return Optional.empty();
  }

  public Charset toCharset() {
    return Charset.forName(charsetName);
  }

  public static List<CsvZeichensatz> getAvailableCsvZeichensatz() {
    List<CsvZeichensatz> result = new ArrayList<>();

    for (CsvZeichensatz csvZeichensatz : values()) {
      if (Charset.isSupported(csvZeichensatz.getCharsetName())) {
        result.add(csvZeichensatz);
      }
    }

    return result;
  }

  public static CsvZeichensatz valueOf(Charset charset) {
    return valueOfOrNullIgnoreCase(charset.name());
  }

  public static CsvZeichensatz valueOfOrNullIgnoreCase(String encoding) {
    if (isNotBlank(encoding)) {
      for (CsvZeichensatz csvZeichensatz : values()) {
        if (equalsIgnoreCase(csvZeichensatz.charsetName, encoding)) {
          return csvZeichensatz;
        }
      }
    }

    return null;
  }
}
