/*
 * Copyright 2017 HugeGraph Authors
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with this
 * work for additional information regarding copyright ownership. The ASF
 * licenses this file to You under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */

package org.apache.hugegraph.unit.util;

import org.junit.Test;

import org.apache.hugegraph.unit.BaseUnitTest;
import org.apache.hugegraph.util.Bytes;
import org.apache.hugegraph.util.NumericUtil;
import org.apache.hugegraph.testutil.Assert;

public class BytesTest extends BaseUnitTest {

    @Test
    public void testBytesEquals() {
        Assert.assertTrue(Bytes.equals(b("12345678"),
                                       b("12345678")));
        Assert.assertTrue(Bytes.equals(new byte[]{1, 3, 5, 7},
                                       new byte[]{1, 3, 5, 7}));

        Assert.assertFalse(Bytes.equals(new byte[]{1, 3, 5, 7},
                                        new byte[]{1, 3, 6, 7}));
        Assert.assertFalse(Bytes.equals(new byte[]{1, 3, 5, 7},
                                        new byte[]{1, 3, 5, 7, 0}));
    }

    @Test
    public void testBytesPrefixWith() {
        Assert.assertTrue(Bytes.prefixWith(b("12345678"), b("12345678")));
        Assert.assertTrue(Bytes.prefixWith(b("12345678"), b("1234567")));

        Assert.assertTrue(Bytes.prefixWith(new byte[]{1, 3, 5, 7},
                                           new byte[]{1, 3, 5, 7}));
        Assert.assertTrue(Bytes.prefixWith(new byte[]{1, 3, 5, 7},
                                           new byte[]{1, 3, 5}));
        Assert.assertTrue(Bytes.prefixWith(new byte[]{1, 3, 5, 7},
                                           new byte[]{1, 3}));

        Assert.assertFalse(Bytes.prefixWith(new byte[]{1, 3, 5, 7},
                                            new byte[]{1, 3, 6, 6}));
        Assert.assertFalse(Bytes.prefixWith(new byte[]{1, 3, 5, 7},
                                            new byte[]{3, 1}));
        Assert.assertFalse(Bytes.prefixWith(new byte[]{1, 3, 5, 7},
                                            new byte[]{1, 3, 5, 7, 0}));
    }

    @Test
    public void testBytesCompare() {
        Assert.assertTrue(Bytes.compare(b("12345678"), b("12345678")) == 0);
        Assert.assertTrue(Bytes.compare(b("12345678"), b("1234567")) > 0);
        Assert.assertTrue(Bytes.compare(b("12345678"), b("12345679")) < 0);

        Assert.assertTrue(Bytes.compare(new byte[]{1, 3, 5, 7},
                                        new byte[]{1, 3, 5, 7}) == 0);

        Assert.assertTrue(Bytes.compare(new byte[]{1, 3, 5, 7},
                                        new byte[]{1, 3, 5, 6}) > 0);

        Assert.assertTrue(Bytes.compare(new byte[]{1, 3, 5, 7},
                                        new byte[]{1, 3, 5}) > 0);

        Assert.assertTrue(Bytes.compare(new byte[]{1, 3, 5, 0},
                                        new byte[]{1, 3, 5}) > 0);

        Assert.assertTrue(Bytes.compare(new byte[]{1, 3, 5, 7},
                                        new byte[]{1, 3}) > 0);

        Assert.assertTrue(Bytes.compare(new byte[]{1, 3, 5, 7},
                                        new byte[]{1, 3, 6, 0}) < 0);

        Assert.assertTrue(Bytes.compare(new byte[]{1, 3, 5, 7},
                                        new byte[]{1, 4}) < 0);

        Assert.assertTrue(Bytes.compare(new byte[]{1, 3, 5, 7},
                                        new byte[]{3, 1}) < 0);

        Assert.assertTrue(Bytes.compare(new byte[]{1, 3, 5, 7},
                                        new byte[]{1, 3, 5, 7, 0}) < 0);

        Assert.assertTrue(Bytes.compare(new byte[]{1, 3, 5, 7},
                                        new byte[]{1, 3, 5, -1}) < 0);

        Assert.assertTrue(Bytes.compare(new byte[]{1, 3, 5, 0},
                                        new byte[]{1, 3, 5, -128}) < 0);

        Assert.assertTrue(Bytes.compare(new byte[]{1, 3, 5, -2},
                                        new byte[]{1, 3, 5, -1}) < 0);

        Assert.assertTrue(Bytes.compare(new byte[]{1, 3, 5, -128},
                                        new byte[]{1, 3, 5, -1}) < 0);
    }

    @Test
    public void testBytesConcat() {
        Assert.assertArrayEquals(b("12345678"),
                                 Bytes.concat(b("1234"), b("5678")));
        Assert.assertArrayEquals(b("12345678"),
                                 Bytes.concat(b("12345678"), b("")));
        Assert.assertArrayEquals(b("12345678"),
                                 Bytes.concat(b(""), b("12345678")));
    }

    @Test
    public void testBytesContains() {
        Assert.assertTrue(Bytes.contains(b("1234"), (byte) '1'));
        Assert.assertTrue(Bytes.contains(b("1234"), (byte) '3'));
        Assert.assertTrue(Bytes.contains(b("1234"), (byte) '4'));

        Assert.assertFalse(Bytes.contains(b("1234"), (byte) '0'));
        Assert.assertFalse(Bytes.contains(b(""), (byte) '0'));
    }

    @Test
    public void testBytesIndexOf() {
        Assert.assertEquals(0, Bytes.indexOf(b("1234"), (byte) '1'));
        Assert.assertEquals(2, Bytes.indexOf(b("1234"), (byte) '3'));
        Assert.assertEquals(3, Bytes.indexOf(b("1234"), (byte) '4'));

        Assert.assertEquals(-1, Bytes.indexOf(b("1234"), (byte) '0'));
        Assert.assertEquals(-1, Bytes.indexOf(b(""), (byte) '0'));
    }

    @Test
    public void testByteToHex() {
        byte value = 0;
        Assert.assertEquals("00", Bytes.toHex(value));

        value = 127;
        Assert.assertEquals("7f", Bytes.toHex(value));

        value = -128;
        Assert.assertEquals("80", Bytes.toHex(value));

        value = -1;
        Assert.assertEquals("ff", Bytes.toHex(value));
    }

    @Test
    public void testBytesToHex() {
        int value = 0x0103807f;
        byte[] bytes = NumericUtil.intToBytes(value);
        Assert.assertEquals("0103807f", Bytes.toHex(bytes));
    }

    @Test
    public void testBytesFromHex() {
        Assert.assertEquals(0x0103807f,
                            NumericUtil.bytesToInt(Bytes.fromHex("0103807f")));
    }

    private static byte[] b(String string) {
        return string.getBytes();
    }
}
