package net.minecraft.resources;

import net.minecraft.IdentifierException;

import com.bergerkiller.bukkit.common.wrappers.ResourceKey;

import com.bergerkiller.generated.net.minecraft.resources.IdentifierHandle;

class Identifier {
#if version >= 1.18
    public String getName:getPath();
    public String getNamespace();
#elseif version >= 1.14.4
    public String getName:getKey();
    public String getNamespace();
#elseif version >= 1.12
    public String getName:getKey();
    public String getNamespace:b();
#elseif version >= 1.9
    public String getName:a();
    public String getNamespace:b();
#else
    public String getName:a();
    public String getNamespace() {
        #require Identifier protected final readonly String namespaceField:a;
        return instance#namespaceField;
    }
#endif

    // Used in generated code. Does not exist on 1.13 and later.
    protected optional transient (Object) Identifier(int code, String[] parts);

#if version >= 1.13
    public static (IdentifierHandle) Identifier createNew(String keyToken) {
        try {
  #if version >= 1.21
            return Identifier.parse(keyToken);
  #else
            return new Identifier(keyToken);
  #endif
        } catch (IdentifierException ex) {
            return null;
        }
    }

    public static optional (IdentifierHandle) Identifier createNew2(String namespace, String name) {
        try {
  #if version >= 1.21
            return Identifier.fromNamespaceAndPath(namespace, name);
  #else
            return new Identifier(namespace, name);
  #endif
        } catch (IdentifierException ex) {
            return null;
        }
    }
#else
    public static (IdentifierHandle) Identifier createNew(String keyToken) {
        if (keyToken == null) {
            return null;
        }
        Identifier key = new Identifier(keyToken);
        String namespace = (String) IdentifierHandle.T.getNamespace.invoke(key);
        String name = (String) IdentifierHandle.T.getName.invoke(key);
        if (!IdentifierHandle.isValidNamespace(namespace)) {
            return null;
        }
        if (!IdentifierHandle.isValidName(name)) {
            return null;
        }
        return key;
    }

    public static optional (IdentifierHandle) Identifier createNew2(String namespace, String name) {
        if (!IdentifierHandle.isValidNamespace(namespace)) {
            return null;
        }
        if (!IdentifierHandle.isValidName(name)) {
            return null;
        }
        return (Identifier) IdentifierHandle.T.constr_code_parts.newInstance(
            Integer.valueOf(0),
            new String[] { namespace, name }
        );
    }
#endif

    public Object toBukkit() {
#if version >= 1.12
        return org.bukkit.craftbukkit.util.CraftNamespacedKey.fromMinecraft(instance);
#else
        throw new UnsupportedOperationException("Bukkit NamespacedKey does not exist before Minecraft 1.12");
#endif
    }

    <code>
    public static final String DEFAULT_NAMESPACE = "minecraft";

    public boolean isDefaultNamespace() {
        return DEFAULT_NAMESPACE.equals(getNamespace());
    }

    public String toShortString() {
        return isDefaultNamespace() ? getName() : toString();
    }

    public static boolean isValid(String key) {
        return createNew(key) != null;
    }

    public static boolean isValidNamespace(String namespace) {
        if (namespace == null || namespace.isEmpty()) {
            // defaults to minecraft namespace in these cases
            return true;
        }
        for (int cidx = 0; cidx < namespace.length(); cidx++) {
            char i = namespace.charAt(cidx);
            if (i == 95 || i == 45 || (i >= 97 && i <= 122) || (i >= 48 && i <= 57) || i == 46) {
                continue;
            }
            return false;
        }
        return true;
    }

    public static boolean isValidName(String name) {
        if (name == null || name.isEmpty()) {
            return false;
        }
        for (int cidx = 0; cidx < name.length(); cidx++) {
            char i = name.charAt(cidx);
            if (i == 95 || i == 45 || (i >= 97 && i <= 122) || (i >= 48 && i <= 57) || i == 47 || i == 46) {
                continue;
            }
            return false;
        }
        return true;
    }

    public static IdentifierHandle createNew(String namespace, String name) {
        return T.createNew2.invoke(namespace, name);
    }
    </code>
}
