/*
 * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 * @test
 * @bug 8323552
 * @run testng TestMismatch
 */

import java.lang.foreign.Arena;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicReference;

import java.lang.foreign.MemorySegment;
import java.lang.foreign.ValueLayout;
import java.util.function.IntFunction;
import java.util.stream.Stream;

import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static java.lang.System.out;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertThrows;

public class TestMismatch {

    // stores an increasing sequence of values into the memory of the given segment
    static MemorySegment initializeSegment(MemorySegment segment) {
        for (int i = 0 ; i < segment.byteSize() ; i++) {
            segment.set(ValueLayout.JAVA_BYTE, i, (byte)i);
        }
        return segment;
    }

    @Test(dataProvider = "slices", expectedExceptions = IndexOutOfBoundsException.class)
    public void testNegativeSrcFromOffset(MemorySegment s1, MemorySegment s2) {
        MemorySegment.mismatch(s1, -1, 0, s2, 0, 0);
    }

    @Test(dataProvider = "slices", expectedExceptions = IndexOutOfBoundsException.class)
    public void testNegativeDstFromOffset(MemorySegment s1, MemorySegment s2) {
        MemorySegment.mismatch(s1, 0, 0, s2, -1, 0);
    }

    @Test(dataProvider = "slices", expectedExceptions = IndexOutOfBoundsException.class)
    public void testNegativeSrcToOffset(MemorySegment s1, MemorySegment s2) {
        MemorySegment.mismatch(s1, 0, -1, s2, 0, 0);
    }

    @Test(dataProvider = "slices", expectedExceptions = IndexOutOfBoundsException.class)
    public void testNegativeDstToOffset(MemorySegment s1, MemorySegment s2) {
        MemorySegment.mismatch(s1, 0, 0, s2, 0, -1);
    }

    @Test(dataProvider = "slices", expectedExceptions = IndexOutOfBoundsException.class)
    public void testNegativeSrcLength(MemorySegment s1, MemorySegment s2) {
        MemorySegment.mismatch(s1, 3, 2, s2, 0, 0);
    }

    @Test(dataProvider = "slices", expectedExceptions = IndexOutOfBoundsException.class)
    public void testNegativeDstLength(MemorySegment s1, MemorySegment s2) {
        MemorySegment.mismatch(s1, 0, 0, s2, 3, 2);
    }

    @Test(dataProvider = "slices")
    public void testSameValues(MemorySegment ss1, MemorySegment ss2) {
        out.format("testSameValues s1:%s, s2:%s\n", ss1, ss2);
        MemorySegment s1 = initializeSegment(ss1);
        MemorySegment s2 = initializeSegment(ss2);

        if (s1.byteSize() == s2.byteSize()) {
            assertEquals(s1.mismatch(s2), -1);  // identical
            assertEquals(s2.mismatch(s1), -1);
        } else if (s1.byteSize() > s2.byteSize()) {
            assertEquals(s1.mismatch(s2), s2.byteSize());  // proper prefix
            assertEquals(s2.mismatch(s1), s2.byteSize());
        } else {
            assert s1.byteSize() < s2.byteSize();
            assertEquals(s1.mismatch(s2), s1.byteSize());  // proper prefix
            assertEquals(s2.mismatch(s1), s1.byteSize());
        }
    }

    @Test(dataProvider = "slicesStatic")
    public void testSameValuesStatic(SliceOffsetAndSize ss1, SliceOffsetAndSize ss2) {
        out.format("testSameValuesStatic s1:%s, s2:%s\n", ss1, ss2);
        MemorySegment s1 = initializeSegment(ss1.toSlice());
        MemorySegment s2 = initializeSegment(ss2.toSlice());

        for (long i = ss2.offset ; i < ss2.size ; i++) {
            long bytes = i - ss2.offset;
            long expected = (bytes == ss1.size) ?
                    -1 : Long.min(ss1.size, bytes);
            assertEquals(MemorySegment.mismatch(ss1.segment, ss1.offset, ss1.endOffset(), ss2.segment, ss2.offset, i), expected);
        }
        for (long i = ss1.offset ; i < ss1.size ; i++) {
            long bytes = i - ss1.offset;
            long expected = (bytes == ss2.size) ?
                    -1 : Long.min(ss2.size, bytes);
            assertEquals(MemorySegment.mismatch(ss2.segment, ss2.offset, ss2.endOffset(), ss1.segment, ss1.offset, i), expected);
        }
    }

    @Test
    public void random() {
        try (var arena = Arena.ofConfined()) {
            var rnd = new Random(42);
            for (int size = 1; size < 64; size++) {
                // Repeat a fair number of rounds
                for (int i = 0; i < 147; i++) {
                    var src = arena.allocate(size);
                    // The dst segment might be zero to eight bytes longer
                    var dst = arena.allocate(size + rnd.nextInt(8 + 1));
                    // Fill the src with random data
                    for (int j = 0; j < size; j++) {
                        src.set(ValueLayout.JAVA_BYTE, j, randomByte(rnd));
                    }
                    // copy the random data from src to dst
                    dst.copyFrom(src);
                    // Fill the rest (if any) of the dst with random data
                    for (long j = src.byteSize(); j < dst.byteSize(); j++) {
                        dst.set(ValueLayout.JAVA_BYTE, j, randomByte(rnd));
                    }

                    if (rnd.nextBoolean()) {
                        // In this branch, we inject one or more deviating bytes
                        int beginDiff = rnd.nextInt(size);
                        int endDiff = rnd.nextInt(beginDiff, size);
                        for (int d = beginDiff; d <= endDiff; d++) {
                            byte existing = dst.get(ValueLayout.JAVA_BYTE, d);
                            // Make sure we never get back the same value
                            byte mutatedValue;
                            do {
                                mutatedValue = randomByte(rnd);
                            } while (existing == mutatedValue);
                            dst.set(ValueLayout.JAVA_BYTE, d, mutatedValue);
                        }

                        // They are not equal and differs in position beginDiff
                        assertEquals(src.mismatch(dst), beginDiff);
                        assertEquals(dst.mismatch(src), beginDiff);
                    } else {
                        // In this branch, there is no injection

                        if (src.byteSize() == dst.byteSize()) {
                            // The content matches and they are of equal size
                            assertEquals(src.mismatch(dst), -1);
                            assertEquals(dst.mismatch(src), -1);
                        } else {
                            // The content matches but they are of different length
                            // Remember, the size of src is always smaller or equal
                            // to the size of dst.
                            assertEquals(src.mismatch(dst), src.byteSize());
                            assertEquals(dst.mismatch(src), src.byteSize());
                        }
                    }
                }
            }
        }
    }

    static byte randomByte(Random rnd) {
        return (byte) rnd.nextInt(Byte.MIN_VALUE, Byte.MAX_VALUE + 1);
    }

    @Test(dataProvider = "slices")
    public void testDifferentValues(MemorySegment s1, MemorySegment s2) {
        out.format("testDifferentValues s1:%s, s2:%s\n", s1, s2);
        s1 = initializeSegment(s1);
        s2 = initializeSegment(s2);

        for (long i = s2.byteSize() -1 ; i >= 0; i--) {
            long expectedMismatchOffset = i;
            s2.set(ValueLayout.JAVA_BYTE, i, (byte) 0xFF);

            if (s1.byteSize() == s2.byteSize()) {
                assertEquals(s1.mismatch(s2), expectedMismatchOffset);
                assertEquals(s2.mismatch(s1), expectedMismatchOffset);
            } else if (s1.byteSize() > s2.byteSize()) {
                assertEquals(s1.mismatch(s2), expectedMismatchOffset);
                assertEquals(s2.mismatch(s1), expectedMismatchOffset);
            } else {
                assert s1.byteSize() < s2.byteSize();
                var off = Math.min(s1.byteSize(), expectedMismatchOffset);
                assertEquals(s1.mismatch(s2), off);  // proper prefix
                assertEquals(s2.mismatch(s1), off);
            }
        }
    }

    @Test(dataProvider = "slicesStatic")
    public void testDifferentValuesStatic(SliceOffsetAndSize ss1, SliceOffsetAndSize ss2) {
        out.format("testDifferentValues s1:%s, s2:%s\n", ss1, ss2);

        for (long i = ss2.size - 1 ; i >= 0; i--) {
            if (i >= ss1.size) continue;
            initializeSegment(ss1.toSlice());
            initializeSegment(ss2.toSlice());
            long expectedMismatchOffset = i;
            ss2.toSlice().set(ValueLayout.JAVA_BYTE, i, (byte) 0xFF);

            for (long j = expectedMismatchOffset + 1 ; j < ss2.size ; j++) {
                assertEquals(MemorySegment.mismatch(ss1.segment, ss1.offset, ss1.endOffset(), ss2.segment, ss2.offset, j + ss2.offset), expectedMismatchOffset);
            }
            for (long j = expectedMismatchOffset + 1 ; j < ss1.size ; j++) {
                assertEquals(MemorySegment.mismatch(ss2.segment, ss2.offset, ss2.endOffset(), ss1.segment, ss1.offset, j + ss1.offset), expectedMismatchOffset);
            }
        }
    }

    @Test
    public void testEmpty() {
        var s1 = MemorySegment.ofArray(new byte[0]);
        assertEquals(s1.mismatch(s1), -1);
        try (Arena arena = Arena.ofConfined()) {
            var nativeSegment = arena.allocate(4, 4);;
            var s2 = nativeSegment.asSlice(0, 0);
            assertEquals(s1.mismatch(s2), -1);
            assertEquals(s2.mismatch(s1), -1);
        }
    }

    @Test
    public void testLarge() {
        // skip if not on 64 bits
        if (ValueLayout.ADDRESS.byteSize() > 32) {
            try (Arena arena = Arena.ofConfined()) {
                var s1 = arena.allocate((long) Integer.MAX_VALUE + 10L, 8);;
                var s2 = arena.allocate((long) Integer.MAX_VALUE + 10L, 8);;
                assertEquals(s1.mismatch(s1), -1);
                assertEquals(s1.mismatch(s2), -1);
                assertEquals(s2.mismatch(s1), -1);

                testLargeAcrossMaxBoundary(s1, s2);

                testLargeMismatchAcrossMaxBoundary(s1, s2);
            }
        }
    }

    private void testLargeAcrossMaxBoundary(MemorySegment s1, MemorySegment s2) {
        for (long i = s2.byteSize() -1 ; i >= Integer.MAX_VALUE - 10L; i--) {
            var s3 = s1.asSlice(0, i);
            var s4 = s2.asSlice(0, i);
            // instance
            assertEquals(s3.mismatch(s3), -1);
            assertEquals(s3.mismatch(s4), -1);
            assertEquals(s4.mismatch(s3), -1);
            // static
            assertEquals(MemorySegment.mismatch(s1, 0, s1.byteSize(), s1, 0, i), -1);
            assertEquals(MemorySegment.mismatch(s2, 0, s1.byteSize(), s1, 0, i), -1);
            assertEquals(MemorySegment.mismatch(s1, 0, s1.byteSize(), s2, 0, i), -1);
        }
    }

    private void testLargeMismatchAcrossMaxBoundary(MemorySegment s1, MemorySegment s2) {
        for (long i = s2.byteSize() -1 ; i >= Integer.MAX_VALUE - 10L; i--) {
            s2.set(ValueLayout.JAVA_BYTE, i, (byte) 0xFF);
            long expectedMismatchOffset = i;
            assertEquals(s1.mismatch(s2), expectedMismatchOffset);
            assertEquals(s2.mismatch(s1), expectedMismatchOffset);
        }
    }

    static final Class<IllegalStateException> ISE = IllegalStateException.class;
    static final Class<UnsupportedOperationException> UOE = UnsupportedOperationException.class;

    @Test
    public void testClosed() {
        MemorySegment s1, s2;
        try (Arena arena = Arena.ofConfined()) {
            s1 = arena.allocate(4, 1);
            s2 = arena.allocate(4, 1);;
        }
        assertThrows(ISE, () -> s1.mismatch(s1));
        assertThrows(ISE, () -> s1.mismatch(s2));
        assertThrows(ISE, () -> s2.mismatch(s1));
    }

    @Test
    public void testThreadAccess() throws Exception {
        try (Arena arena = Arena.ofConfined()) {
            var segment = arena.allocate(4, 1);;
            {
                AtomicReference<RuntimeException> exception = new AtomicReference<>();
                Runnable action = () -> {
                    try {
                        MemorySegment.ofArray(new byte[4]).mismatch(segment);
                    } catch (RuntimeException e) {
                        exception.set(e);
                    }
                };
                Thread thread = new Thread(action);
                thread.start();
                thread.join();

                RuntimeException e = exception.get();
                if (!(e instanceof WrongThreadException)) {
                    throw e;
                }
            }
            {
                AtomicReference<RuntimeException> exception = new AtomicReference<>();
                Runnable action = () -> {
                    try {
                        segment.mismatch(MemorySegment.ofArray(new byte[4]));
                    } catch (RuntimeException e) {
                        exception.set(e);
                    }
                };
                Thread thread = new Thread(action);
                thread.start();
                thread.join();

                RuntimeException e = exception.get();
                if (!(e instanceof WrongThreadException)) {
                    throw e;
                }
            }
        }
    }

    @Test
    public void testSameSegment() {
        var segment = MemorySegment.ofArray(new byte[]{
                1,2,3,4,  1,2,3,4,  1,4});

        long match = MemorySegment.mismatch(
                segment, 0L, 4L,
                segment, 4L, 8L);
        assertEquals(match, -1);

        long noMatch = MemorySegment.mismatch(
                segment, 0L, 4L,
                segment, 1L, 5L);
        assertEquals(noMatch, 0);

        long noMatchEnd = MemorySegment.mismatch(
                segment, 0L, 2L,
                segment, 8L, 10L);
        assertEquals(noMatchEnd, 1);

        long same = MemorySegment.mismatch(
                segment, 0L, 8L,
                segment, 0L, 8L);
        assertEquals(same, -1);
    }

    enum SegmentKind {
        NATIVE(i -> Arena.ofAuto().allocate(i, 1)),
        ARRAY(i -> MemorySegment.ofArray(new byte[i]));

        final IntFunction<MemorySegment> segmentFactory;

        SegmentKind(IntFunction<MemorySegment> segmentFactory) {
            this.segmentFactory = segmentFactory;
        }

        MemorySegment makeSegment(int elems) {
            return segmentFactory.apply(elems);
        }
    }

    record SliceOffsetAndSize(MemorySegment segment, long offset, long size) {
        MemorySegment toSlice() {
            return segment.asSlice(offset, size);
        }
        long endOffset() {
            return offset + size;
        }
    };

    @DataProvider(name = "slicesStatic")
    static Object[][] slicesStatic() {
        int[] sizes = { 16, 8, 1 };
        List<SliceOffsetAndSize> aSliceOffsetAndSizes = new ArrayList<>();
        List<SliceOffsetAndSize> bSliceOffsetAndSizes = new ArrayList<>();
        for (List<SliceOffsetAndSize> slices : List.of(aSliceOffsetAndSizes, bSliceOffsetAndSizes)) {
            for (SegmentKind kind : SegmentKind.values()) {
                MemorySegment segment = kind.makeSegment(16);
                //compute all slices
                for (int size : sizes) {
                    for (int index = 0 ; index < 16 ; index += size) {
                        slices.add(new SliceOffsetAndSize(segment, index, size));
                    }
                }
            }
        }
        assert aSliceOffsetAndSizes.size() == bSliceOffsetAndSizes.size();
        Object[][] sliceArray = new Object[aSliceOffsetAndSizes.size() * bSliceOffsetAndSizes.size()][];
        for (int i = 0 ; i < aSliceOffsetAndSizes.size() ; i++) {
            for (int j = 0 ; j < bSliceOffsetAndSizes.size() ; j++) {
                sliceArray[i * aSliceOffsetAndSizes.size() + j] = new Object[] { aSliceOffsetAndSizes.get(i), bSliceOffsetAndSizes.get(j) };
            }
        }
        return sliceArray;
    }

    @DataProvider(name = "slices")
    static Object[][] slices() {
        Object[][] slicesStatic = slicesStatic();
        return Stream.of(slicesStatic)
                .map(arr -> new Object[]{
                        ((SliceOffsetAndSize) arr[0]).toSlice(),
                        ((SliceOffsetAndSize) arr[1]).toSlice()
                }).toArray(Object[][]::new);
    }
}
