/*
 * Copyright (c) 2022 MiLaboratories Inc.
 *
 * Licensed 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 com.milaboratory.util;

import junit.framework.TestCase;
import org.apache.commons.math3.random.Well19937c;
import org.junit.Assert;

import java.util.Arrays;
import java.util.HashSet;

public class ByteStringTest extends TestCase {
    public void testSpeed1() {
        Well19937c r = RandomUtil.getThreadLocalRandom();

        ByteString[] strings = new ByteString[1000000];
        for (int i = 0; i < strings.length; i++) {
            byte[] b = new byte[100];
            r.nextBytes(b);
            strings[i] = ByteString.createNoCopy(b);
        }

        int s = 0;
        long start = System.nanoTime();
        for (ByteString string : strings) s += string.hashCode();
        System.out.println("Time per hash: " + FormatUtils.nanoTimeToString((System.nanoTime() - start) / strings.length));

        HashSet<ByteString> set = new HashSet<>();

        start = System.nanoTime();
        for (ByteString string : strings) set.add(string);
        System.out.println("Addition to hash set (per operation): " + FormatUtils.nanoTimeToString((System.nanoTime() - start) / strings.length));

        start = System.nanoTime();
        for (ByteString string : strings) set.remove(string);
        System.out.println("Hash set removal (per operation): " + FormatUtils.nanoTimeToString((System.nanoTime() - start) / strings.length));

        // prevent compiler optimization
        System.out.println(s > 0 ? 'a' : 'b');
    }

    public void testToString() {
        Assert.assertEquals("Hello", ByteString.create("Hello".getBytes()).toString());
        Assert.assertEquals("0102fa", ByteString.create((byte) 1, (byte) 2, (byte) 0xFA).toString());
    }

    public void testOrdering() {
        ByteString[] strings = new ByteString[]{
                ByteString.fromString("ATTA"),
                ByteString.fromString("AT"),
                ByteString.fromString("GC"),
                ByteString.fromString("ATTAG"),
                ByteString.fromString("ATTAC"),
        };
        ByteString[] stringsExpected = new ByteString[]{
                ByteString.fromString("AT"),
                ByteString.fromString("ATTA"),
                ByteString.fromString("ATTAC"),
                ByteString.fromString("ATTAG"),
                ByteString.fromString("GC"),
        };
        Arrays.sort(strings);
        Assert.assertArrayEquals(stringsExpected, strings);
    }
}
