package com.atlassian.bitbucket.mesh.partition;

import javax.annotation.Nonnull;
import java.util.regex.Pattern;

import static java.util.Objects.requireNonNull;

public class Partition implements Comparable<Partition> {

    // A partition name can be up to 15 hex characters (60 bits) because we're using a long to
    // store them. We cut off the last byte (1 hex character) to ensure the parsed number can
    // never be negative. We also don't want to have a hex character whose max value is '7' instead
    // of 'f' as a hidden "gotcha".
    private static final Pattern PATTERN_PARTITION = Pattern.compile("[0-9a-f]{4,15}");

    private final String name;
    private final long number;

    public Partition(@Nonnull String name) {
        this.name = requireNonNull(name, "name");

        if (!PATTERN_PARTITION.matcher(name).matches()) {
            throw new InvalidPartitionNameException(name);
        }

        number = Long.parseUnsignedLong(name, 16);
    }

    @Override
    public int compareTo(Partition o) {
        return Long.compareUnsigned(number, o.number);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof Partition)) {
            return false;
        }
        Partition that = (Partition) o;

        return number == that.number;
    }

    @Nonnull
    public String getHex() {
        return name;
    }

    @Override
    public int hashCode() {
        return Long.hashCode(number);
    }

    @Override
    public String toString() {
        return "Partition " + name;
    }
}
