/*
 * Copyright (c) 2023, 2025, 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 id=specialized
 * @library ../
 * @requires (!(os.name == "Mac OS X" & os.arch == "aarch64") | jdk.foreign.linker != "FALLBACK")
 * @modules java.base/jdk.internal.foreign
 * @run testng/othervm/native
 *   --enable-native-access=ALL-UNNAMED
 *   -Djdk.internal.foreign.DowncallLinker.USE_SPEC=true
 *   -Djdk.internal.foreign.UpcallLinker.USE_SPEC=true
 *   TestArrayStructs
 */

/*
 * @test id=interpreted
 * @library ../
 * @requires (!(os.name == "Mac OS X" & os.arch == "aarch64") | jdk.foreign.linker != "FALLBACK")
 * @modules java.base/jdk.internal.foreign
 * @run testng/othervm/native
 *   --enable-native-access=ALL-UNNAMED
 *   -Djdk.internal.foreign.DowncallLinker.USE_SPEC=false
 *   -Djdk.internal.foreign.UpcallLinker.USE_SPEC=false
 *   TestArrayStructs
 */

import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import java.lang.foreign.Arena;
import java.lang.foreign.FunctionDescriptor;
import java.lang.foreign.MemoryLayout;
import java.lang.foreign.MemorySegment;
import java.lang.foreign.StructLayout;
import java.lang.invoke.MethodHandle;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.stream.Stream;

import static java.lang.foreign.MemoryLayout.sequenceLayout;
import static java.lang.foreign.MemoryLayout.structLayout;

public class TestArrayStructs extends NativeTestHelper {
    static {
        System.loadLibrary("ArrayStructs");
    }

    // Test if structs of various different sizes, including non-powers of two, work correctly
    @Test(dataProvider = "arrayStructs")
    public void testArrayStruct(String functionName, FunctionDescriptor baseDesc, int numPrefixArgs, int numElements) throws Throwable {
        FunctionDescriptor downcallDesc = baseDesc.insertArgumentLayouts(0, C_POINTER); // CB
        MemoryLayout[] elementLayouts = Collections.nCopies(numElements, C_CHAR).toArray(MemoryLayout[]::new);
        FunctionDescriptor upcallDesc = baseDesc.appendArgumentLayouts(elementLayouts);
        try (Arena arena = Arena.ofConfined()) {
            TestValue[] testArgs = genTestArgs(baseDesc, arena);

            MethodHandle downcallHandle = downcallHandle(functionName, downcallDesc);
            Object[] args = new Object[downcallDesc.argumentLayouts().size() + 1]; // +1 for return allocator
            AtomicReference<Object[]> returnBox = new AtomicReference<>();
            int returnIdx = numPrefixArgs;
            int argIdx = 0;
            args[argIdx++] = arena;
            args[argIdx++] = makeArgSaverCB(upcallDesc, arena, returnBox, returnIdx);
            for (TestValue testArg : testArgs) {
                args[argIdx++] = testArg.value();
            }

            MemorySegment returned = (MemorySegment) downcallHandle.invokeWithArguments(args);
            Consumer<Object> structCheck = testArgs[returnIdx].check();

            structCheck.accept(returned);

            Object[] capturedArgs = returnBox.get();
            int capturedArgIdx;
            for (capturedArgIdx = numPrefixArgs; capturedArgIdx < testArgs.length; capturedArgIdx++) {
                testArgs[capturedArgIdx].check().accept(capturedArgs[capturedArgIdx]);
            }

            byte[] elements = new byte[numElements];
            for (int elIdx = 0; elIdx < numElements; elIdx++, capturedArgIdx++) {
                elements[elIdx] = (byte) capturedArgs[capturedArgIdx];
            }

            structCheck.accept(MemorySegment.ofArray(elements)); // reuse the check for the struct
        }
    }

    @DataProvider
    public static Object[][] arrayStructs() {
        List<Object[]> cases = new ArrayList<>();
        for (int i = 0; i < layouts.size(); i++) {
            StructLayout layout = layouts.get(i);
            int numElements = i + 1;
            cases.add(new Object[]{"F" + numElements, FunctionDescriptor.of(layout, layout), 0, numElements});
        }
        for (int i = 0; i < layouts.size(); i++) {
            StructLayout layout = layouts.get(i);
            MemoryLayout[] argLayouts = Stream.concat(PREFIX_LAYOUTS.stream(), Stream.of(layout)).toArray(MemoryLayout[]::new);
            int numElements = i + 1;
            cases.add(new Object[]{"F" + numElements + "_stack", FunctionDescriptor.of(layout, argLayouts), PREFIX_LAYOUTS.size(), numElements});
        }

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

    static final List<MemoryLayout> PREFIX_LAYOUTS = List.of(
        C_LONG_LONG, C_LONG_LONG, C_LONG_LONG, C_LONG_LONG, C_LONG_LONG, C_LONG_LONG, C_LONG_LONG, C_LONG_LONG,
        C_DOUBLE, C_DOUBLE, C_DOUBLE, C_DOUBLE, C_DOUBLE, C_DOUBLE, C_DOUBLE, C_DOUBLE);

    static final List<StructLayout> layouts = List.of(
        structLayout(sequenceLayout(1, C_CHAR).withName("f0")).withName("S1"),
        structLayout(sequenceLayout(2, C_CHAR).withName("f0")).withName("S2"),
        structLayout(sequenceLayout(3, C_CHAR).withName("f0")).withName("S3"),
        structLayout(sequenceLayout(4, C_CHAR).withName("f0")).withName("S4"),
        structLayout(sequenceLayout(5, C_CHAR).withName("f0")).withName("S5"),
        structLayout(sequenceLayout(6, C_CHAR).withName("f0")).withName("S6"),
        structLayout(sequenceLayout(7, C_CHAR).withName("f0")).withName("S7"),
        structLayout(sequenceLayout(8, C_CHAR).withName("f0")).withName("S8"),
        structLayout(sequenceLayout(9, C_CHAR).withName("f0")).withName("S9"),
        structLayout(sequenceLayout(10, C_CHAR).withName("f0")).withName("S10"),
        structLayout(sequenceLayout(11, C_CHAR).withName("f0")).withName("S11"),
        structLayout(sequenceLayout(12, C_CHAR).withName("f0")).withName("S12"),
        structLayout(sequenceLayout(13, C_CHAR).withName("f0")).withName("S13"),
        structLayout(sequenceLayout(14, C_CHAR).withName("f0")).withName("S14"),
        structLayout(sequenceLayout(15, C_CHAR).withName("f0")).withName("S15"),
        structLayout(sequenceLayout(16, C_CHAR).withName("f0")).withName("S16"));
}
