// Copyright 2021 The Dawn Authors
//
// 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.

#include "tests/DawnTest.h"

#include "common/Math.h"
#include "utils/WGPUHelpers.h"

#include <array>
#include <functional>

namespace {

    // Helper for replacing all occurrences of substr in str with replacement
    std::string ReplaceAll(std::string str,
                           const std::string& substr,
                           const std::string& replacement) {
        size_t pos = 0;
        while ((pos = str.find(substr, pos)) != std::string::npos) {
            str.replace(pos, substr.length(), replacement);
            pos += replacement.length();
        }
        return str;
    }

    // DataMatcherCallback is the callback function by DataMatcher.
    // It is called for each contiguous sequence of bytes that should be checked
    // for equality.
    // offset and size are in units of bytes.
    using DataMatcherCallback = std::function<void(uint32_t offset, uint32_t size)>;

    // DataMatcher is a function pointer to a data matching function.
    // size is the total number of bytes being considered for matching.
    // The callback may be called once or multiple times, and may only consider
    // part of the interval [0, size)
    using DataMatcher = void (*)(uint32_t size, DataMatcherCallback);

    // FullDataMatcher is a DataMatcher that calls callback with the interval
    // [0, size)
    void FullDataMatcher(uint32_t size, DataMatcherCallback callback) {
        callback(0, size);
    }

    // StridedDataMatcher is a DataMatcher that calls callback with the strided
    // intervals of length BYTES_TO_MATCH, skipping BYTES_TO_SKIP.
    // For example: StridedDataMatcher<2, 4>(18, callback) will call callback
    // with the intervals: [0, 2), [6, 8), [12, 14)
    template <int BYTES_TO_MATCH, int BYTES_TO_SKIP>
    void StridedDataMatcher(uint32_t size, DataMatcherCallback callback) {
        uint32_t offset = 0;
        while (offset < size) {
            callback(offset, BYTES_TO_MATCH);
            offset += BYTES_TO_MATCH + BYTES_TO_SKIP;
        }
    }

    // Align returns the WGSL decoration for an explicit structure field alignment
    std::string AlignDeco(uint32_t value) {
        return "[[align(" + std::to_string(value) + ")]] ";
    }

}  // namespace

// Field holds test parameters for ComputeLayoutMemoryBufferTests.Fields
struct Field {
    const char* type;  // Type of the field
    uint32_t align;    // Alignment of the type in bytes
    uint32_t size;     // Natural size of the type in bytes

    uint32_t padded_size = 0;                // Decorated (extended) size of the type in bytes
    DataMatcher matcher = &FullDataMatcher;  // The matching method
    bool storage_buffer_only = false;        // This should only be used for storage buffer tests

    // Sets the padded_size to value.
    // Returns this Field so calls can be chained.
    Field& PaddedSize(uint32_t value) {
        padded_size = value;
        return *this;
    }

    // Sets the matcher to a StridedDataMatcher<BYTES_TO_MATCH, BYTES_TO_SKIP>.
    // Returns this Field so calls can be chained.
    template <int BYTES_TO_MATCH, int BYTES_TO_SKIP>
    Field& Strided() {
        matcher = &StridedDataMatcher<BYTES_TO_MATCH, BYTES_TO_SKIP>;
        return *this;
    }

    // Marks that this should only be used for storage buffer tests.
    // Returns this Field so calls can be chained.
    Field& StorageBufferOnly() {
        storage_buffer_only = true;
        return *this;
    }
};

// StorageClass is an enumerator of storage classes used by ComputeLayoutMemoryBufferTests.Fields
enum class StorageClass {
    Uniform,
    Storage,
};

std::ostream& operator<<(std::ostream& o, StorageClass storageClass) {
    switch (storageClass) {
        case StorageClass::Uniform:
            o << "uniform";
            break;
        case StorageClass::Storage:
            o << "storage";
            break;
    }
    return o;
}

std::ostream& operator<<(std::ostream& o, Field field) {
    o << "[[align(" << field.align << "), size("
      << (field.padded_size > 0 ? field.padded_size : field.size) << ")]] " << field.type;
    return o;
}

DAWN_TEST_PARAM_STRUCT(ComputeLayoutMemoryBufferTestParams, StorageClass, Field);

class ComputeLayoutMemoryBufferTests
    : public DawnTestWithParams<ComputeLayoutMemoryBufferTestParams> {
    void SetUp() override {
        DawnTestBase::SetUp();
    }
};

TEST_P(ComputeLayoutMemoryBufferTests, Fields) {
    // Sentinel value markers codes used to check that the start and end of
    // structures are correctly aligned. Each of these codes are distinct and
    // are not likely to be confused with data.
    constexpr uint32_t kDataHeaderCode = 0xa0b0c0a0u;
    constexpr uint32_t kDataFooterCode = 0x40302010u;
    constexpr uint32_t kInputHeaderCode = 0x91827364u;
    constexpr uint32_t kInputFooterCode = 0x19283764u;

    // Byte codes used for field padding. The MSB is set for each of these.
    // The field data has the MSB 0.
    constexpr uint8_t kDataAlignPaddingCode = 0xfeu;
    constexpr uint8_t kFieldAlignPaddingCode = 0xfdu;
    constexpr uint8_t kFieldSizePaddingCode = 0xdcu;
    constexpr uint8_t kDataSizePaddingCode = 0xdbu;
    constexpr uint8_t kInputFooterAlignPaddingCode = 0xdau;
    constexpr uint8_t kInputTailPaddingCode = 0xd9u;

    // Status codes returned by the shader.
    constexpr uint32_t kStatusBadInputHeader = 100u;
    constexpr uint32_t kStatusBadInputFooter = 101u;
    constexpr uint32_t kStatusBadDataHeader = 102u;
    constexpr uint32_t kStatusBadDataFooter = 103u;
    constexpr uint32_t kStatusOk = 200u;

    const Field& field = GetParam().mField;

    const bool isUniform = GetParam().mStorageClass == StorageClass::Uniform;

    std::string shader = R"(
struct Data {
    header : u32;
    [[align({field_align}), size({field_size})]] field : {field_type};
    footer : u32;
};

struct Input {
    header : u32;
    {data_align}data : Data;
    {footer_align}footer : u32;
};

struct Output {
    data : {field_type};
};

struct Status {
    code : u32;
};

[[group(0), binding(0)]] var<{input_qualifiers}> input : Input;
[[group(0), binding(1)]] var<storage, read_write> output : Output;
[[group(0), binding(2)]] var<storage, read_write> status : Status;

[[stage(compute), workgroup_size(1,1,1)]]
fn main() {
    if (input.header != {input_header_code}u) {
        status.code = {status_bad_input_header}u;
    } elseif (input.footer != {input_footer_code}u) {
        status.code = {status_bad_input_footer}u;
    } elseif (input.data.header != {data_header_code}u) {
        status.code = {status_bad_data_header}u;
    } elseif (input.data.footer != {data_footer_code}u) {
        status.code = {status_bad_data_footer}u;
    } else {
        status.code = {status_ok}u;
        output.data = input.data.field;
    }
})";

    // https://www.w3.org/TR/WGSL/#alignment-and-size
    // Structure size: roundUp(AlignOf(S), OffsetOf(S, L) + SizeOf(S, L))
    // https://www.w3.org/TR/WGSL/#storage-class-constraints
    // RequiredAlignOf(S, uniform): roundUp(16, max(AlignOf(T0), ..., AlignOf(TN)))
    uint32_t dataAlign = isUniform ? std::max(16u, field.align) : field.align;

    // https://www.w3.org/TR/WGSL/#structure-layout-rules
    // Note: When underlying the target is a Vulkan device, we assume the device does not support
    // the scalarBlockLayout feature. Therefore, a data value must not be placed in the padding at
    // the end of a structure or matrix, nor in the padding at the last element of an array.
    uint32_t footerAlign = isUniform ? 16 : 4;

    shader = ReplaceAll(shader, "{data_align}", isUniform ? AlignDeco(dataAlign) : "");
    shader = ReplaceAll(shader, "{field_align}", std::to_string(field.align));
    shader = ReplaceAll(shader, "{footer_align}", isUniform ? AlignDeco(footerAlign) : "");
    shader = ReplaceAll(shader, "{field_size}",
                        std::to_string(field.padded_size > 0 ? field.padded_size : field.size));
    shader = ReplaceAll(shader, "{field_type}", field.type);
    shader = ReplaceAll(shader, "{input_header_code}", std::to_string(kInputHeaderCode));
    shader = ReplaceAll(shader, "{input_footer_code}", std::to_string(kInputFooterCode));
    shader = ReplaceAll(shader, "{data_header_code}", std::to_string(kDataHeaderCode));
    shader = ReplaceAll(shader, "{data_footer_code}", std::to_string(kDataFooterCode));
    shader = ReplaceAll(shader, "{status_bad_input_header}", std::to_string(kStatusBadInputHeader));
    shader = ReplaceAll(shader, "{status_bad_input_footer}", std::to_string(kStatusBadInputFooter));
    shader = ReplaceAll(shader, "{status_bad_data_header}", std::to_string(kStatusBadDataHeader));
    shader = ReplaceAll(shader, "{status_bad_data_footer}", std::to_string(kStatusBadDataFooter));
    shader = ReplaceAll(shader, "{status_ok}", std::to_string(kStatusOk));
    shader = ReplaceAll(shader, "{input_qualifiers}",
                        isUniform ? "uniform"  //
                                  : "storage, read_write");

    // Set up shader and pipeline
    auto module = utils::CreateShaderModule(device, shader.c_str());

    wgpu::ComputePipelineDescriptor csDesc;
    csDesc.compute.module = module;
    csDesc.compute.entryPoint = "main";

    wgpu::ComputePipeline pipeline = device.CreateComputePipeline(&csDesc);

    // Build the input and expected data.
    std::vector<uint8_t> inputData;     // The whole SSBO data
    std::vector<uint8_t> expectedData;  // The expected data to be copied by the shader
    {
        auto PushU32 = [&inputData](uint32_t u32) {
            inputData.emplace_back((u32 >> 0) & 0xff);
            inputData.emplace_back((u32 >> 8) & 0xff);
            inputData.emplace_back((u32 >> 16) & 0xff);
            inputData.emplace_back((u32 >> 24) & 0xff);
        };
        auto AlignTo = [&inputData](uint32_t alignment, uint8_t code) {
            uint32_t target = Align(inputData.size(), alignment);
            uint32_t bytes = target - inputData.size();
            for (uint32_t i = 0; i < bytes; i++) {
                inputData.emplace_back(code);
            }
        };
        PushU32(kInputHeaderCode);                  // Input.header
        AlignTo(dataAlign, kDataAlignPaddingCode);  // Input.data
        {
            PushU32(kDataHeaderCode);                      // Input.data.header
            AlignTo(field.align, kFieldAlignPaddingCode);  // Input.data.field
            for (uint32_t i = 0; i < field.size; i++) {
                // The data has the MSB cleared to distinguish it from the
                // padding codes.
                uint8_t code = i & 0x7f;
                inputData.emplace_back(code);  // Input.data.field
                expectedData.emplace_back(code);
            }
            for (uint32_t i = field.size; i < field.padded_size; i++) {
                inputData.emplace_back(kFieldSizePaddingCode);  // Input.data.field padding
            }
            PushU32(kDataFooterCode);                    // Input.data.footer
            AlignTo(field.align, kDataSizePaddingCode);  // Input.data padding
        }
        AlignTo(footerAlign, kInputFooterAlignPaddingCode);  // Input.footer [[align]]
        PushU32(kInputFooterCode);                           // Input.footer
        AlignTo(256, kInputTailPaddingCode);                 // Input padding
    }

    // Set up input storage buffer
    wgpu::Buffer inputBuf = utils::CreateBufferFromData(
        device, inputData.data(), inputData.size(),
        wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst |
            (isUniform ? wgpu::BufferUsage::Uniform : wgpu::BufferUsage::Storage));

    // Set up output storage buffer
    wgpu::BufferDescriptor outputDesc;
    outputDesc.size = field.size;
    outputDesc.usage =
        wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
    wgpu::Buffer outputBuf = device.CreateBuffer(&outputDesc);

    // Set up status storage buffer
    wgpu::BufferDescriptor statusDesc;
    statusDesc.size = 4u;
    statusDesc.usage =
        wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
    wgpu::Buffer statusBuf = device.CreateBuffer(&statusDesc);

    // Set up bind group and issue dispatch
    wgpu::BindGroup bindGroup = utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
                                                     {
                                                         {0, inputBuf},
                                                         {1, outputBuf},
                                                         {2, statusBuf},
                                                     });

    wgpu::CommandBuffer commands;
    {
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
        pass.SetPipeline(pipeline);
        pass.SetBindGroup(0, bindGroup);
        pass.Dispatch(1);
        pass.EndPass();

        commands = encoder.Finish();
    }

    queue.Submit(1, &commands);

    // Check the status
    EXPECT_BUFFER_U32_EQ(kStatusOk, statusBuf, 0) << "status code error" << std::endl
                                                  << "Shader: " << shader;

    // Check the data
    field.matcher(field.size, [&](uint32_t offset, uint32_t size) {
        EXPECT_BUFFER_U8_RANGE_EQ(expectedData.data() + offset, outputBuf, offset, size)
            << "offset: " << offset;
    });
}

namespace {

    auto GenerateParams() {
        auto params = MakeParamGenerator<ComputeLayoutMemoryBufferTestParams>(
            {
                D3D12Backend(), MetalBackend(), VulkanBackend(),
                // TODO(crbug.com/dawn/942)
                // There was a compiler error: Buffer block cannot be expressed as any of std430,
                // std140, scalar, even with enhanced layouts. You can try flattening this block to
                // support a more flexible layout.
                // OpenGLBackend(),
                // OpenGLESBackend(),
            },
            {StorageClass::Storage, StorageClass::Uniform},
            {
                // See https://www.w3.org/TR/WGSL/#alignment-and-size
                // Scalar types with no custom alignment or size
                Field{"i32", /* align */ 4, /* size */ 4},
                Field{"u32", /* align */ 4, /* size */ 4},
                Field{"f32", /* align */ 4, /* size */ 4},

                // Scalar types with custom alignment
                Field{"i32", /* align */ 16, /* size */ 4},
                Field{"u32", /* align */ 16, /* size */ 4},
                Field{"f32", /* align */ 16, /* size */ 4},

                // Scalar types with custom size
                Field{"i32", /* align */ 4, /* size */ 4}.PaddedSize(24),
                Field{"u32", /* align */ 4, /* size */ 4}.PaddedSize(24),
                Field{"f32", /* align */ 4, /* size */ 4}.PaddedSize(24),

                // Vector types with no custom alignment or size
                Field{"vec2<i32>", /* align */ 8, /* size */ 8},
                Field{"vec2<u32>", /* align */ 8, /* size */ 8},
                Field{"vec2<f32>", /* align */ 8, /* size */ 8},
                Field{"vec3<i32>", /* align */ 16, /* size */ 12},
                Field{"vec3<u32>", /* align */ 16, /* size */ 12},
                Field{"vec3<f32>", /* align */ 16, /* size */ 12},
                Field{"vec4<i32>", /* align */ 16, /* size */ 16},
                Field{"vec4<u32>", /* align */ 16, /* size */ 16},
                Field{"vec4<f32>", /* align */ 16, /* size */ 16},

                // Vector types with custom alignment
                Field{"vec2<i32>", /* align */ 32, /* size */ 8},
                Field{"vec2<u32>", /* align */ 32, /* size */ 8},
                Field{"vec2<f32>", /* align */ 32, /* size */ 8},
                Field{"vec3<i32>", /* align */ 32, /* size */ 12},
                Field{"vec3<u32>", /* align */ 32, /* size */ 12},
                Field{"vec3<f32>", /* align */ 32, /* size */ 12},
                Field{"vec4<i32>", /* align */ 32, /* size */ 16},
                Field{"vec4<u32>", /* align */ 32, /* size */ 16},
                Field{"vec4<f32>", /* align */ 32, /* size */ 16},

                // Vector types with custom size
                Field{"vec2<i32>", /* align */ 8, /* size */ 8}.PaddedSize(24),
                Field{"vec2<u32>", /* align */ 8, /* size */ 8}.PaddedSize(24),
                Field{"vec2<f32>", /* align */ 8, /* size */ 8}.PaddedSize(24),
                Field{"vec3<i32>", /* align */ 16, /* size */ 12}.PaddedSize(24),
                Field{"vec3<u32>", /* align */ 16, /* size */ 12}.PaddedSize(24),
                Field{"vec3<f32>", /* align */ 16, /* size */ 12}.PaddedSize(24),
                Field{"vec4<i32>", /* align */ 16, /* size */ 16}.PaddedSize(24),
                Field{"vec4<u32>", /* align */ 16, /* size */ 16}.PaddedSize(24),
                Field{"vec4<f32>", /* align */ 16, /* size */ 16}.PaddedSize(24),

                // Matrix types with no custom alignment or size
                Field{"mat2x2<f32>", /* align */ 8, /* size */ 16},
                Field{"mat3x2<f32>", /* align */ 8, /* size */ 24},
                Field{"mat4x2<f32>", /* align */ 8, /* size */ 32},
                Field{"mat2x3<f32>", /* align */ 16, /* size */ 32}.Strided<12, 4>(),
                Field{"mat3x3<f32>", /* align */ 16, /* size */ 48}.Strided<12, 4>(),
                Field{"mat4x3<f32>", /* align */ 16, /* size */ 64}.Strided<12, 4>(),
                Field{"mat2x4<f32>", /* align */ 16, /* size */ 32},
                Field{"mat3x4<f32>", /* align */ 16, /* size */ 48},
                Field{"mat4x4<f32>", /* align */ 16, /* size */ 64},

                // Matrix types with custom alignment
                Field{"mat2x2<f32>", /* align */ 32, /* size */ 16},
                Field{"mat3x2<f32>", /* align */ 32, /* size */ 24},
                Field{"mat4x2<f32>", /* align */ 32, /* size */ 32},
                Field{"mat2x3<f32>", /* align */ 32, /* size */ 32}.Strided<12, 4>(),
                Field{"mat3x3<f32>", /* align */ 32, /* size */ 48}.Strided<12, 4>(),
                Field{"mat4x3<f32>", /* align */ 32, /* size */ 64}.Strided<12, 4>(),
                Field{"mat2x4<f32>", /* align */ 32, /* size */ 32},
                Field{"mat3x4<f32>", /* align */ 32, /* size */ 48},
                Field{"mat4x4<f32>", /* align */ 32, /* size */ 64},

                // Matrix types with custom size
                Field{"mat2x2<f32>", /* align */ 8, /* size */ 16}.PaddedSize(128),
                Field{"mat3x2<f32>", /* align */ 8, /* size */ 24}.PaddedSize(128),
                Field{"mat4x2<f32>", /* align */ 8, /* size */ 32}.PaddedSize(128),
                Field{"mat2x3<f32>", /* align */ 16, /* size */ 32}
                    .PaddedSize(128)
                    .Strided<12, 4>(),
                Field{"mat3x3<f32>", /* align */ 16, /* size */ 48}
                    .PaddedSize(128)
                    .Strided<12, 4>(),
                Field{"mat4x3<f32>", /* align */ 16, /* size */ 64}
                    .PaddedSize(128)
                    .Strided<12, 4>(),
                Field{"mat2x4<f32>", /* align */ 16, /* size */ 32}.PaddedSize(128),
                Field{"mat3x4<f32>", /* align */ 16, /* size */ 48}.PaddedSize(128),
                Field{"mat4x4<f32>", /* align */ 16, /* size */ 64}.PaddedSize(128),

                // Array types with no custom alignment, size or stride
                // Note: The use of StorageBufferOnly() is due to UBOs requiring 16 byte alignment
                // of array elements. See https://www.w3.org/TR/WGSL/#storage-class-constraints
                Field{"array<u32, 1>", /* align */ 4, /* size */ 4}.StorageBufferOnly(),
                Field{"array<u32, 2>", /* align */ 4, /* size */ 8}.StorageBufferOnly(),
                Field{"array<u32, 3>", /* align */ 4, /* size */ 12}.StorageBufferOnly(),
                Field{"array<u32, 4>", /* align */ 4, /* size */ 16}.StorageBufferOnly(),
                Field{"[[stride(16)]] array<u32, 1>", /* align */ 4, /* size */ 16}
                    .StorageBufferOnly()
                    .Strided<4, 12>(),
                Field{"[[stride(16)]] array<u32, 2>", /* align */ 4, /* size */ 32}
                    .StorageBufferOnly()
                    .Strided<4, 12>(),
                Field{"[[stride(16)]] array<u32, 3>", /* align */ 4, /* size */ 48}
                    .StorageBufferOnly()
                    .Strided<4, 12>(),
                Field{"[[stride(16)]] array<u32, 4>", /* align */ 4, /* size */ 64}
                    .StorageBufferOnly()
                    .Strided<4, 12>(),
                Field{"array<vec3<u32>, 4>", /* align */ 16, /* size */ 64}.Strided<12, 4>(),
                Field{"[[stride(32)]] array<vec3<u32>, 4>", /* align */ 16, /* size */ 128}
                    .Strided<12, 20>(),

                // Array types with custom alignment
                Field{"array<u32, 1>", /* align */ 32, /* size */ 4}.StorageBufferOnly(),
                Field{"array<u32, 2>", /* align */ 32, /* size */ 8}.StorageBufferOnly(),
                Field{"array<u32, 3>", /* align */ 32, /* size */ 12}.StorageBufferOnly(),
                Field{"array<u32, 4>", /* align */ 32, /* size */ 16}.StorageBufferOnly(),
                Field{"[[stride(16)]] array<u32, 1>", /* align */ 32, /* size */ 16}
                    .Strided<4, 12>(),
                Field{"[[stride(16)]] array<u32, 2>", /* align */ 32, /* size */ 32}
                    .Strided<4, 12>(),
                Field{"[[stride(16)]] array<u32, 3>", /* align */ 32, /* size */ 48}
                    .Strided<4, 12>(),
                Field{"[[stride(16)]] array<u32, 4>", /* align */ 32, /* size */ 64}
                    .Strided<4, 12>(),
                Field{"array<vec3<u32>, 4>", /* align */ 32, /* size */ 64}.Strided<12, 4>(),

                // Array types with custom size
                Field{"array<u32, 1>", /* align */ 4, /* size */ 4}
                    .PaddedSize(128)
                    .StorageBufferOnly(),
                Field{"array<u32, 2>", /* align */ 4, /* size */ 8}
                    .PaddedSize(128)
                    .StorageBufferOnly(),
                Field{"array<u32, 3>", /* align */ 4, /* size */ 12}
                    .PaddedSize(128)
                    .StorageBufferOnly(),
                Field{"array<u32, 4>", /* align */ 4, /* size */ 16}
                    .PaddedSize(128)
                    .StorageBufferOnly(),
                Field{"array<vec3<u32>, 4>", /* align */ 16, /* size */ 64}
                    .PaddedSize(128)
                    .Strided<12, 4>(),
            });

        std::vector<ComputeLayoutMemoryBufferTestParams> filtered;
        for (auto param : params) {
            if (param.mStorageClass != StorageClass::Storage && param.mField.storage_buffer_only) {
                continue;
            }
            filtered.emplace_back(param);
        }
        return filtered;
    }

    INSTANTIATE_TEST_SUITE_P(
        ,
        ComputeLayoutMemoryBufferTests,
        ::testing::ValuesIn(GenerateParams()),
        DawnTestBase::PrintToStringParamName("ComputeLayoutMemoryBufferTests"));
    GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ComputeLayoutMemoryBufferTests);

}  // namespace
