package org.bukkit.craftbukkit.tag;

import java.util.Objects;
import net.minecraft.core.HolderSet;
import net.minecraft.core.Registry;
import net.minecraft.tags.TagKey;
import org.bukkit.Keyed;
import org.bukkit.NamespacedKey;
import org.bukkit.Tag;
import org.bukkit.craftbukkit.util.CraftNamespacedKey;

public abstract class CraftTag<N, B extends Keyed> implements Tag<B> {

    protected final Registry<N> registry;
    protected final TagKey<N> tag;

    private final HolderSet.Named<N> handle;

    public CraftTag(Registry<N> registry, TagKey<N> tag) {
        this.registry = registry;
        this.tag = tag;
        this.handle = registry.get(this.tag).orElseThrow();
    }

    public HolderSet.Named<N> getHandle() {
        return this.handle;
    }

    @Override
    public NamespacedKey getKey() {
        return CraftNamespacedKey.fromMinecraft(this.tag.location());
    }

    @Override
    public int hashCode() {
        int hash = 3;
        hash = 59 * hash + Objects.hashCode(this.registry);
        hash = 59 * hash + Objects.hashCode(this.tag);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }

        if (!(obj instanceof CraftTag<?, ?> other)) {
            return false;
        }

        return Objects.equals(this.registry, other.registry) && Objects.equals(this.tag, other.tag);
    }

    @Override
    public String toString() {
        return "CraftTag{" + this.tag + '}';
    }
}
