package de.duehl.basics.io;

/*
 * Copyright 2026 Christian Dühl. All rights reserved.
 *
 * This program is free software. You can redistribute it and/or
 * modify it under the same terms as perl:
 *
 * general:  http://dev.perl.org/licenses/
 * GPL:      http://dev.perl.org/licenses/gpl1.html
 * artistic: http://dev.perl.org/licenses/artistic.html
 */

import java.nio.charset.StandardCharsets;

/**
 * Enum für die Charsets.
 *
 * @see java.nio.charset.Charset
 *
 * @version 1.03     2026-07-09
 * @author Christian Dühl
 */

public enum Charset {

    US_ASCII(
            "US-ASCII",
            "Seven-bit ASCII, a.k.a. ISO646-US, a.k.a. the Basic Latin block of the Unicode "
                    + "character set",
            StandardCharsets.US_ASCII),
    ISO_8859_1(
            "ISO-8859-1",
            "ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1",
            StandardCharsets.ISO_8859_1),
    UTF_8(
            "UTF-8",
            "Eight-bit UCS Transformation Format",
            StandardCharsets.UTF_8),
    UTF_16BE(
            "UTF-16BE",
            "Sixteen-bit UCS Transformation Format, big-endian byte order",
            StandardCharsets.UTF_16BE),
    UTF_16LE(
            "UTF-16LE",
            "Sixteen-bit UCS Transformation Format, little-endian byte order",
            StandardCharsets.UTF_16LE),
    UTF_16(
            "UTF-16",
            "Sixteen-bit UCS Transformation Format, byte order identified by an optional "
                    + "byte-order mark",
            StandardCharsets.UTF_16),
    ;

    // "Cp1252" ?

    /** Hübschere Darstellung des Charsets in Stringform. */
    private final String charsetAsString;

    /** Beschreibung des Charsets. */
    private final String description;

    /** Das zugehörige java.nio.charset.Charset. */
    private final java.nio.charset.Charset nioCharset;

    /**
     * Konstruktor.
     *
     * @param charsetAsString
     *            Hübschere Darstellung des Charsets in Stringform.
     * @param description
     *            Beschreibung des Charsets.
     */
    private Charset(String charsetAsString, String description,
            java.nio.charset.Charset nioCharset) {
        this.charsetAsString = charsetAsString;
        this.description = description;
        this.nioCharset = nioCharset;
    }

    /** Getter für die hübschere Darstellung des Charsets in Stringform. */
    public String getCharsetAsString() {
        return charsetAsString;
    }

    /** Getter für die Beschreibung des Charsets. */
    public String getDescription() {
        return description;
    }

    /** Getter für das zugehörige java.nio.charset.Charset. */
    public java.nio.charset.Charset getNioCharset() {
        return nioCharset;
    }

    /** Gibt das Default-Charset zurück. */
    public static Charset getDefaultCharset() {
        return ISO_8859_1;
    }

    /** Ermittelt das passende Objekt zum angegebenen Namen. */
    public static Charset detectFromNameString(String name) {
        try {
            return Charset.valueOf(name);
        }
        catch (IllegalArgumentException exception) {
            throw new IllegalArgumentException("Es ist kein Charset mit dem Namen '" + name
                    + "' bekannt!");
        }
    }

    /** Ermittelt das passende Objekt zur angegebenen Stringform des Charsets. */
    public static Charset detectFromCharsetAsString(String charsetAsString) {
        for (Charset charset : Charset.values()) {
            if (charsetAsString.equalsIgnoreCase(charset.getCharsetAsString())) {
                return charset;
            }
        }

        throw new IllegalArgumentException("Es ist kein Charset mit der angegebenen Stringform "
                + "des Charsets '" + charsetAsString + "' bekannt!");
    }

    /** Gibt eine Beschreibung der enthaltenen Charsets zurück. */
    public static String createCompleteCharsetDescription() {
        StringBuilder builder = new StringBuilder();

        builder.append("Übersicht über die Charsets:\n");

        int maxNameLength = 0;
        int maxCharsetAsStringLength = 0;
        for (Charset charset : Charset.values()) {
            if (maxNameLength < charset.name().length()) {
                maxNameLength = charset.name().length();
            }
            if (maxCharsetAsStringLength < charset.getCharsetAsString().length()) {
                maxCharsetAsStringLength = charset.getCharsetAsString().length();
            }
        }
        String nameLengthForFormat = "%-" + maxNameLength + "s";
        String charsetAsStringLengthForFormat = "%-" + maxCharsetAsStringLength + "s";

        for (Charset charset : Charset.values()) {
            String name = charset.name();
            String charsetAsString = charset.getCharsetAsString();
            String description = charset.getDescription();
            builder.append(String.format(
                    nameLengthForFormat + " - " + charsetAsStringLengthForFormat + " - " + "%s\n",
                    name, charsetAsString, description));
        }

        return builder.toString();
    }

    /** Gibt eine Beschreibung der enthaltenen Charsets zurück. */
    public static String createCompleteCharsetDescriptionWithOnlyName() {
        StringBuilder builder = new StringBuilder();

        builder.append("Übersicht über die Charsets:\n");

        int maxNameLength = 0;
        for (Charset charset : Charset.values()) {
            if (maxNameLength < charset.name().length()) {
                maxNameLength = charset.name().length();
            }
        }
        String nameLengthForFormat = "%-" + maxNameLength + "s";

        for (Charset charset : Charset.values()) {
            String name = charset.name();
            String description = charset.getDescription();
            builder.append(String.format(nameLengthForFormat + " - " + "%s\n", name, description));
        }

        return builder.toString();
    }

    /** Gibt eine Beschreibung der enthaltenen Charsets zurück. */
    public static String createCompleteCharsetDescriptionWithOnlyCharsetAsString() {
        StringBuilder builder = new StringBuilder();

        builder.append("Übersicht über die Charsets:\n");

        int maxCharsetAsStringLength = 0;
        for (Charset charset : Charset.values()) {
            if (maxCharsetAsStringLength < charset.getCharsetAsString().length()) {
                maxCharsetAsStringLength = charset.getCharsetAsString().length();
            }
        }
        String charsetAsStringLengthForFormat = "%-" + maxCharsetAsStringLength + "s";

        for (Charset charset : Charset.values()) {
            String charsetAsString = charset.getCharsetAsString();
            String description = charset.getDescription();
            builder.append(String.format(charsetAsStringLengthForFormat + " - " + "%s\n",
                    charsetAsString, description));
        }

        return builder.toString();
    }

}
