// 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 "dawn/common/Math.h"
#include "dawn/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;
    } else if (input.footer != {input_footer_code}u) {
        status.code = {status_bad_input_footer}u;
    } else if (input.data.header != {data_header_code}u) {
        status.code = {status_bad_data_header}u;
    } else if (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.End();

        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
