/*
 * Copyright (c) 2022, 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
 * @modules java.base/jdk.internal.foreign java.base/jdk.internal.foreign.abi.fallback
 * @run testng TestLinker
 * @run testng/othervm TestLinker
 */

import jdk.internal.foreign.CABI;
import jdk.internal.foreign.abi.fallback.FallbackLinker;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import java.lang.foreign.FunctionDescriptor;
import java.lang.foreign.Linker;
import java.lang.foreign.MemoryLayout;
import java.lang.foreign.PaddingLayout;
import java.lang.foreign.SequenceLayout;
import java.lang.foreign.StructLayout;
import java.lang.foreign.ValueLayout;
import java.lang.invoke.MethodHandle;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static java.lang.foreign.MemoryLayout.*;
import static java.lang.foreign.ValueLayout.*;
import static org.testng.Assert.*;

public class TestLinker extends NativeTestHelper {

    static final boolean IS_FALLBACK_LINKER = CABI.current() == CABI.FALLBACK;

    record LinkRequest(FunctionDescriptor descriptor, Linker.Option... options) {}

    @Test(dataProvider = "notSameCases")
    public void testLinkerOptionsCache(LinkRequest l1, LinkRequest l2) {
        Linker linker = Linker.nativeLinker();
        MethodHandle mh1 = linker.downcallHandle(l1.descriptor(), l1.options());
        MethodHandle mh2 = linker.downcallHandle(l2.descriptor(), l2.options());
        // assert that these are 2 distinct link request. No caching allowed
        assertNotSame(mh1, mh2);
    }

    @DataProvider
    public static Object[][] notSameCases() {
        FunctionDescriptor fd_II_V = FunctionDescriptor.ofVoid(C_INT, C_INT);
        return new Object[][]{
            {new LinkRequest(fd_II_V), new LinkRequest(fd_II_V, Linker.Option.firstVariadicArg(1))},
            {new LinkRequest(FunctionDescriptor.ofVoid(JAVA_SHORT)), new LinkRequest(FunctionDescriptor.ofVoid(JAVA_CHAR))},
            {new LinkRequest(FunctionDescriptor.ofVoid(JAVA_SHORT)), new LinkRequest(FunctionDescriptor.ofVoid(JAVA_CHAR))},
        };
    }

    @Test(dataProvider = "namedDescriptors")
    public void testNamedLinkerCache(FunctionDescriptor f1, FunctionDescriptor f2) {
        Linker linker = Linker.nativeLinker();
        MethodHandle mh1 = linker.downcallHandle(f1);
        MethodHandle mh2 = linker.downcallHandle(f2);
        // assert that these are the same link request, even though layout names differ
        assertSame(mh1, mh2);
    }

    @DataProvider
    public static Object[][] namedDescriptors() {
        List<Object[]> cases = new ArrayList<>(Arrays.asList(new Object[][]{
            { FunctionDescriptor.ofVoid(C_INT),
                    FunctionDescriptor.ofVoid(C_INT.withName("x")) },
            { FunctionDescriptor.ofVoid(structLayout(C_INT)),
                    FunctionDescriptor.ofVoid(structLayout(C_INT).withName("x")) },
            { FunctionDescriptor.ofVoid(structLayout(C_INT)),
                    FunctionDescriptor.ofVoid(structLayout(C_INT.withName("x"))) },
            { FunctionDescriptor.ofVoid(structLayout(sequenceLayout(1, C_INT))),
                    FunctionDescriptor.ofVoid(structLayout(sequenceLayout(1, C_INT).withName("x"))) },
            { FunctionDescriptor.ofVoid(structLayout(sequenceLayout(1, C_INT))),
                    FunctionDescriptor.ofVoid(structLayout(sequenceLayout(1, C_INT.withName("x")))) },
            { FunctionDescriptor.ofVoid(C_POINTER),
                    FunctionDescriptor.ofVoid(C_POINTER.withName("x")) },
            { FunctionDescriptor.ofVoid(C_POINTER.withTargetLayout(C_INT)),
                    FunctionDescriptor.ofVoid(C_POINTER.withTargetLayout(C_INT.withName("x"))) },
            { FunctionDescriptor.ofVoid(C_POINTER.withTargetLayout(C_INT)),
                    FunctionDescriptor.ofVoid(C_POINTER.withName("x").withTargetLayout(C_INT.withName("x"))) },
        }));

        if (!IS_FALLBACK_LINKER) {
            cases.add(new Object[]{ FunctionDescriptor.ofVoid(unionLayout(C_INT)),
                    FunctionDescriptor.ofVoid(unionLayout(C_INT).withName("x")) });
            cases.add(new Object[]{ FunctionDescriptor.ofVoid(unionLayout(C_INT)),
                    FunctionDescriptor.ofVoid(unionLayout(C_INT.withName("x"))) });
        }
        if (C_LONG_LONG.byteAlignment() == 8) {
            cases.add(new Object[]{ FunctionDescriptor.ofVoid(structLayout(C_INT, paddingLayout(4), C_LONG_LONG)),
                    FunctionDescriptor.ofVoid(structLayout(C_INT, paddingLayout(4), C_LONG_LONG.withName("x"))) });
            cases.add(new Object[]{ FunctionDescriptor.ofVoid(structLayout(C_INT, paddingLayout(4), C_LONG_LONG)),
                    FunctionDescriptor.ofVoid(structLayout(C_INT, paddingLayout(4).withName("x"), C_LONG_LONG)) });
        }

        return cases.toArray(Object[][]::new);
    }

    @DataProvider
    public static Object[][] invalidIndexCases() {
        return new Object[][]{
                { -1, },
                { 42, },
        };
    }

    @Test(dataProvider = "invalidIndexCases",
          expectedExceptions = IllegalArgumentException.class,
          expectedExceptionsMessageRegExp = ".*not in bounds for descriptor.*")
    public void testInvalidOption(int invalidIndex) {
        Linker.Option option = Linker.Option.firstVariadicArg(invalidIndex);
        FunctionDescriptor desc = FunctionDescriptor.ofVoid();
        Linker.nativeLinker().downcallHandle(desc, option); // throws
    }

    @Test(expectedExceptions = IllegalArgumentException.class,
          expectedExceptionsMessageRegExp = ".*Unknown name.*")
    public void testInvalidPreservedValueName() {
        Linker.Option.captureCallState("foo"); // throws
    }

    @Test(dataProvider = "canonicalTypeNames")
    public void testCanonicalLayouts(String typeName) {
        MemoryLayout layout = LINKER.canonicalLayouts().get(typeName);
        assertNotNull(layout);
        assertTrue(layout instanceof ValueLayout);
    }

    @Test
    public void embeddedPaddingLayout() {
        PaddingLayout padding = MemoryLayout.paddingLayout(64).withByteAlignment(64);
        SequenceLayout sequence = MemoryLayout.sequenceLayout(2, padding);
        StructLayout struct = MemoryLayout.structLayout(sequence);
        FunctionDescriptor fd = FunctionDescriptor.of(struct, struct);
        Linker linker = Linker.nativeLinker();
        var x = expectThrows(IllegalArgumentException.class, () -> linker.downcallHandle(fd));
        assertTrue(x.getMessage().contains("not supported because a sequence of a padding layout is not allowed"));
    }

    @Test
    public void groupLayoutWithOnlyPadding() {
        PaddingLayout padding = MemoryLayout.paddingLayout(1);
        StructLayout struct = MemoryLayout.structLayout(padding);
        FunctionDescriptor fd = FunctionDescriptor.of(struct, struct);
        Linker linker = Linker.nativeLinker();
        var x = expectThrows(IllegalArgumentException.class, () -> linker.downcallHandle(fd));
        assertTrue(x.getMessage().contains("is non-empty and only has padding layouts"));
    }

    @Test
    public void interwovenPadding() {
        Linker linker = Linker.nativeLinker();
        var padding1 = MemoryLayout.paddingLayout(1);
        var padding2 = MemoryLayout.paddingLayout(2).withByteAlignment(2);

        var struct = MemoryLayout.structLayout(JAVA_BYTE, padding1, padding2, JAVA_INT);

        var fd = FunctionDescriptor.of(struct, struct, struct);
        var e = expectThrows(IllegalArgumentException.class, () -> linker.downcallHandle(fd));
        assertEquals(e.getMessage(),
                "The padding layout x2 was preceded by another padding layout x1 in " + struct);
    }

    @Test
    public void stackedPadding() {
        Linker linker = Linker.nativeLinker();
        var struct32 = MemoryLayout.structLayout(MemoryLayout.sequenceLayout(4, JAVA_LONG));
        var padding1 = MemoryLayout.paddingLayout(1);
        var padding2 = MemoryLayout.paddingLayout(2).withByteAlignment(2);
        var padding4 = MemoryLayout.paddingLayout(4).withByteAlignment(4);
        var padding8 = MemoryLayout.paddingLayout(8).withByteAlignment(8);
        var padding16 = MemoryLayout.paddingLayout(16).withByteAlignment(16);
        var padding32 = MemoryLayout.paddingLayout(32).withByteAlignment(32);
        var union = MemoryLayout.unionLayout(struct32, padding32);
        var struct = MemoryLayout.structLayout(JAVA_BYTE, padding1, padding2, padding4, padding8, padding16, union);
        var fd = FunctionDescriptor.of(struct, struct, struct);
        var e = expectThrows(IllegalArgumentException.class, () -> linker.downcallHandle(fd));
        assertEquals(e.getMessage(),
                "The padding layout x2 was preceded by another padding layout x1 in " + struct);
    }

    @Test
    public void paddingUnionByteSize3() {
        Linker linker = Linker.nativeLinker();
        var union = MemoryLayout.unionLayout(MemoryLayout.paddingLayout(3), ValueLayout.JAVA_INT);
        var fd = FunctionDescriptor.of(union, union, union);
        var e = expectThrows(IllegalArgumentException.class, () -> linker.downcallHandle(fd));
        assertEquals(e.getMessage(), "Superfluous padding x3 in " + union);
    }

    @Test
    public void paddingUnionByteSize4() {
        Linker linker = Linker.nativeLinker();
        var union = MemoryLayout.unionLayout(MemoryLayout.paddingLayout(4), ValueLayout.JAVA_INT);
        var fd = FunctionDescriptor.of(union, union, union);
        var e = expectThrows(IllegalArgumentException.class, () -> linker.downcallHandle(fd));
        assertEquals(e.getMessage(), "Superfluous padding x4 in " + union);
    }

    @Test
    public void paddingUnionByteSize5() {
        Linker linker = Linker.nativeLinker();
        var union = MemoryLayout.unionLayout(MemoryLayout.paddingLayout(5), ValueLayout.JAVA_INT);
        var fd = FunctionDescriptor.of(union, union, union);
        var e = expectThrows(IllegalArgumentException.class, () -> linker.downcallHandle(fd));
        assertEquals(e.getMessage(), "Layout '" + union + "' has unexpected size: 5 != 4");
    }

    @Test
    public void paddingUnionSeveral() {
        Linker linker = Linker.nativeLinker();
        var union = MemoryLayout.unionLayout(
                MemoryLayout.sequenceLayout(3, ValueLayout.JAVA_INT),
                ValueLayout.JAVA_LONG,
                MemoryLayout.paddingLayout(16),
                MemoryLayout.paddingLayout(16));
        var fd = FunctionDescriptor.of(union, union, union);
        var e = expectThrows(IllegalArgumentException.class, () -> linker.downcallHandle(fd));
        assertEquals(e.getMessage(), "More than one padding in " + union);
    }

    @Test
    public void sequenceOfZeroElements() {
        Linker linker = Linker.nativeLinker();
        var sequence0a8 = MemoryLayout.sequenceLayout(0, JAVA_LONG);
        var sequence3a1 = MemoryLayout.sequenceLayout(3, JAVA_BYTE);
        var padding5a1 = MemoryLayout.paddingLayout(5);
        var struct8a8 = MemoryLayout.structLayout(sequence0a8, sequence3a1, padding5a1);
        var fd = FunctionDescriptor.of(struct8a8, struct8a8, struct8a8);
        if (linker.getClass().equals(FallbackLinker.class)) {
            // The fallback linker does not support empty layouts (FFI_BAD_TYPEDEF)
            var iae = expectThrows(IllegalArgumentException.class, () -> linker.downcallHandle(fd));
            assertTrue(iae.getMessage().contains("is empty"));
        } else {
            linker.downcallHandle(fd);
        }
    }

    @DataProvider
    public static Object[][] canonicalTypeNames() {
        return new Object[][]{
                { "bool" },
                { "char" },
                { "short" },
                { "int" },
                { "long" },
                { "long long" },
                { "float" },
                { "double" },
                { "void*" },
                { "size_t" },
                { "wchar_t" },
        };
    }

    @Test(expectedExceptions=UnsupportedOperationException.class)
    public void testCanonicalLayoutsUnmodifiable() {
        LINKER.canonicalLayouts().put("asdf", C_INT);
    }
}
