package lc.stack.zero;

import lc.mecha.nio.ByteBufferUtil;

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Objects;

/**
 * Class representing a ZDP beacon packet.
 *
 * @author Alex Leigh
 */
public class Beacon {
    public static byte FLAG_AUTHORITATIVE = 0x1;
    private final boolean isAuthoritative;
    private final String zaiUrl;

    public Beacon(boolean isAuthoritative, String zaiUrl) {
        this.isAuthoritative = isAuthoritative;
        this.zaiUrl = zaiUrl;
    }

    public Beacon(byte[] packet) {
        ByteBuffer buf = ByteBuffer.wrap(packet);
        int magic = buf.getShort();
        if (magic != 5200) throw new IllegalStateException("Invalid magic number.");
        byte flags = buf.get();
        isAuthoritative = ((flags & FLAG_AUTHORITATIVE) == FLAG_AUTHORITATIVE);
        zaiUrl = ByteBufferUtil.getString(buf);
    }

    /**
     * Returns <code>true</code> if this beacon is authoritative.
     */
    public boolean isAuthoritative() {
        return isAuthoritative;
    }

    /**
     * Write the contents of this beacon out to the provided byte buffer in packet format.
     */
    public void write(ByteBuffer buf) {
        // We don't need to worry about endian here because we're already big endian
        byte[] url = zaiUrl.getBytes(StandardCharsets.UTF_8);

        // Does not include the trailing 0
        if (url.length > 511) throw new IllegalStateException("ZAI URL too long.");

        buf.putShort((short) 5200);
        buf.put((byte) 0);
        buf.put(url);
        buf.put((byte) 0);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Beacon beacon = (Beacon) o;
        return isAuthoritative == beacon.isAuthoritative && Objects.equals(zaiUrl, beacon.zaiUrl);
    }

    @Override
    public int hashCode() {
        return Objects.hash(isAuthoritative, zaiUrl);
    }

    public String getZaiUrl() {
        return zaiUrl;
    }

    @Override
    public String toString() {
        return "Beacon{" +
                "isAuthoritative=" + isAuthoritative +
                ", zaiUrl='" + zaiUrl + '\'' +
                '}';
    }
}
