/*
    Реализация спецификаций CLDC версии 1.1 (JSR-139), MIDP версии 2.1 (JSR-118)
    и других спецификаций для функционирования компактных приложений на языке
    Java (мидлетов) в среде программного обеспечения Малик Эмулятор.

    Copyright © 2016–2017, 2019–2022 Малик Разработчик

    Это свободная программа: вы можете перераспространять ее и/или изменять
    ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
    в каком она была опубликована Фондом свободного программного обеспечения;
    либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.

    Эта программа распространяется в надежде, что она будет полезной,
    но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
    или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
    общественной лицензии GNU.

    Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
    вместе с этой программой. Если это не так, см.
    <https://www.gnu.org/licenses/>.
*/

package javax.bluetooth;

public class UUID extends Object
{
    private final long loHalf;
    private final long hiHalf;

    public UUID(long value) {
        if(value < 0x00000000L || value > 0xffffffffL)
        {
            throw new IllegalArgumentException("UUID: аргумент value выходит из диапазона.");
        }
        this.loHalf = value;
        this.hiHalf = 0L;
    }

    public UUID(String value, boolean isShort) {
        int len;
        int offset;
        long loHalf;
        long hiHalf;
        char[] digits;
        if(value == null)
        {
            throw new NullPointerException("UUID: аргумент value равен нулевой ссылке.");
        }
        if((len = value.length()) <= 0 || len > (isShort ? 8 : 32))
        {
            throw new IllegalArgumentException("UUID: длина аргумента value выходит из диапазона.");
        }
        Array.fill(digits = new char[32], 0, offset = 32 - len, '0');
        value.getChars(0, len, digits, offset);
        loHalf = hiHalf = 0L;
        for(int bits = 0, i = 32; i-- > 0; bits += 4)
        {
            int digit = digits[i];
            long mask;
            if(digit >= '0' && digit <= '9')
            {
                mask = (long) (digit - '0') << bits;
            }
            else if(digit >= 'a' && digit <= 'f')
            {
                mask = (long) (digit - ('a' - 0x0a)) << bits;
            }
            else if(digit >= 'A' && digit <= 'F')
            {
                mask = (long) (digit - ('A' - 0x0a)) << bits;
            }
            else
            {
                throw new NumberFormatException("UUID: недопустимый формат числа.");
            }
            if(bits >= 64)
            {
                hiHalf |= mask;
            } else
            {
                loHalf |= mask;
            }
        }
        this.loHalf = loHalf;
        this.hiHalf = hiHalf;
    }

    public boolean equals(Object anot) {
        UUID uuid;
        return anot instanceof UUID && loHalf == (uuid = (UUID) anot).loHalf && hiHalf == uuid.hiHalf;
    }

    public int hashCode() {
        long half;
        return (int) ((half = loHalf) ^ (half >> 32) ^ (half = hiHalf) ^ (half >> 32));
    }

    public String toString() {
        int offset = 31;
        long loHalf = this.loHalf;
        long hiHalf = this.hiHalf;
        char[] digits = new char[32];
        for(int bits = 0, i = 32; i-- > 0; bits += 4)
        {
            int digit = (int) ((bits >= 64 ? hiHalf : loHalf) >> bits) & 0x0f;
            digits[i] = (char) (digit >= 0x0a ? digit + ('A' - 0x0a) : digit + '0');
        }
        for(int i = 0; i < 31; i++) if(digits[i] != '0')
        {
            offset = i;
            break;
        }
        return new String(digits, offset, 32 - offset);
    }

    final boolean realEquals(UUID uuid) {
        return uuid != null && loHalf == uuid.loHalf && hiHalf == uuid.hiHalf;
    }
}
