/*
 * Copyright (C) 2019 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "WHLSLIntrinsics.h"

#if ENABLE(WEBGPU)

#include "WHLSLConstantExpression.h"
#include "WHLSLTypeArgument.h"
#include "WHLSLTypeReference.h"
#include <algorithm>
#include <cstring>

namespace WebCore {

namespace WHLSL {

constexpr const char* Intrinsics::m_textureTypeNames[];
constexpr const char* Intrinsics::m_textureInnerTypeNames[];
constexpr const char* Intrinsics::m_depthTextureInnerTypes[];

Intrinsics::Intrinsics()
{
}

void Intrinsics::add(AST::NativeFunctionDeclaration& nativeFunctionDeclaration)
{
    if (nativeFunctionDeclaration.name() == "ddx")
        m_ddx = &nativeFunctionDeclaration;
    else if (nativeFunctionDeclaration.name() == "ddy")
        m_ddy = &nativeFunctionDeclaration;
    else if (nativeFunctionDeclaration.name() == "AllMemoryBarrierWithGroupSync")
        m_allMemoryBarrier = &nativeFunctionDeclaration;
    else if (nativeFunctionDeclaration.name() == "DeviceMemoryBarrierWithGroupSync")
        m_deviceMemoryBarrier = &nativeFunctionDeclaration;
    else if (nativeFunctionDeclaration.name() == "GroupMemoryBarrierWithGroupSync")
        m_groupMemoryBarrier = &nativeFunctionDeclaration;
}

bool Intrinsics::addPrimitive(AST::NativeTypeDeclaration& nativeTypeDeclaration)
{
    if (nativeTypeDeclaration.typeArguments().size())
        return false;

    if (nativeTypeDeclaration.name() == "void")
        m_voidType = &nativeTypeDeclaration;
    else if (nativeTypeDeclaration.name() == "bool")
        m_boolType = &nativeTypeDeclaration;
    else if (nativeTypeDeclaration.name() == "uint") {
        nativeTypeDeclaration.setIsInt();
        nativeTypeDeclaration.setIsNumber();
        nativeTypeDeclaration.setCanRepresentInteger([](int x) {
            return x >= 0;
        });
        nativeTypeDeclaration.setCanRepresentUnsignedInteger([](unsigned) {
            return true;
        });
        nativeTypeDeclaration.setCanRepresentFloat([](float x) {
            return static_cast<float>(static_cast<uint32_t>(x)) == x;
        });
        nativeTypeDeclaration.setSuccessor([](int64_t x) -> int64_t {
            return static_cast<uint32_t>(x + 1);
        });
        nativeTypeDeclaration.setFormatValueFromInteger([](int x) -> int64_t {
            return static_cast<uint32_t>(x);
        });
        nativeTypeDeclaration.setFormatValueFromUnsignedInteger([](unsigned x) -> int64_t {
            return static_cast<uint32_t>(x);
        });
        nativeTypeDeclaration.setIterateAllValues([](const std::function<bool(int64_t)>& callback) {
            for (int64_t i = 0; i < 0x100000000; ++i) {
                if (callback(i))
                    break;
            }
        });
        m_uintType = &nativeTypeDeclaration;
    } else if (nativeTypeDeclaration.name() == "int") {
        nativeTypeDeclaration.setIsInt();
        nativeTypeDeclaration.setIsNumber();
        nativeTypeDeclaration.setIsSigned();
        nativeTypeDeclaration.setCanRepresentInteger([](int) {
            return true;
        });
        nativeTypeDeclaration.setCanRepresentUnsignedInteger([](unsigned x) {
            return x <= 2147483647;
        });
        nativeTypeDeclaration.setCanRepresentFloat([](float x) {
            return static_cast<float>(static_cast<int32_t>(x)) == x;
        });
        nativeTypeDeclaration.setSuccessor([](int64_t x) -> int64_t {
            return static_cast<int32_t>(x + 1);
        });
        nativeTypeDeclaration.setFormatValueFromInteger([](int x) -> int64_t {
            return static_cast<int32_t>(x);
        });
        nativeTypeDeclaration.setFormatValueFromUnsignedInteger([](unsigned x) -> int64_t {
            return static_cast<int32_t>(x);
        });
        nativeTypeDeclaration.setIterateAllValues([](const std::function<bool(int64_t)>& callback) {
            for (int64_t i = -2147483647; i < 2147483648; ++i) {
                if (callback(i))
                    break;
            }
        });
        m_intType = &nativeTypeDeclaration;
    } else if (nativeTypeDeclaration.name() == "float") {
        nativeTypeDeclaration.setIsNumber();
        nativeTypeDeclaration.setIsFloating();
        nativeTypeDeclaration.setCanRepresentInteger([](int) {
            return true;
        });
        nativeTypeDeclaration.setCanRepresentUnsignedInteger([](unsigned) {
            return true;
        });
        nativeTypeDeclaration.setCanRepresentFloat([](float) {
            return true;
        });
        m_floatType = &nativeTypeDeclaration;
    } else if (nativeTypeDeclaration.name() == "atomic_int") {
        nativeTypeDeclaration.setIsAtomic();
        m_atomicIntType = &nativeTypeDeclaration;
    } else if (nativeTypeDeclaration.name() == "atomic_uint") {
        nativeTypeDeclaration.setIsAtomic();
        m_atomicUintType = &nativeTypeDeclaration;
    } else if (nativeTypeDeclaration.name() == "sampler") {
        m_samplerType = &nativeTypeDeclaration;
        nativeTypeDeclaration.setIsOpaqueType();
    } else
        ASSERT_NOT_REACHED();
    return true;
}

bool Intrinsics::addVector(AST::NativeTypeDeclaration& nativeTypeDeclaration)
{
    if (nativeTypeDeclaration.name() != "vector")
        return false;

    ASSERT(nativeTypeDeclaration.typeArguments().size() == 2);
    ASSERT(WTF::holds_alternative<Ref<AST::TypeReference>>(nativeTypeDeclaration.typeArguments()[0]));
    ASSERT(WTF::holds_alternative<AST::ConstantExpression>(nativeTypeDeclaration.typeArguments()[1]));
    auto& innerType = static_cast<AST::TypeReference&>(WTF::get<Ref<AST::TypeReference>>(nativeTypeDeclaration.typeArguments()[0]));
    auto& lengthExpression = WTF::get<AST::ConstantExpression>(nativeTypeDeclaration.typeArguments()[1]);
    ASSERT(!innerType.typeArguments().size());
    AST::NativeTypeDeclaration** array;
    if (innerType.name() == "bool")
        array = m_vectorBool;
    else if (innerType.name() == "uint")
        array = m_vectorUint;
    else if (innerType.name() == "int")
        array = m_vectorInt;
    else {
        ASSERT(innerType.name() == "float");
        array = m_vectorFloat;
    }
    int length = lengthExpression.integerLiteral().value();
    ASSERT(length >= 2 && length <= 4);
    nativeTypeDeclaration.setIsVector();
    array[length - 2] = &nativeTypeDeclaration;
    return true;
}

bool Intrinsics::addMatrix(AST::NativeTypeDeclaration& nativeTypeDeclaration)
{
    if (nativeTypeDeclaration.name() != "matrix")
        return false;

    nativeTypeDeclaration.setIsMatrix();

    ASSERT(nativeTypeDeclaration.typeArguments().size() == 3);
    ASSERT(WTF::holds_alternative<Ref<AST::TypeReference>>(nativeTypeDeclaration.typeArguments()[0]));
    ASSERT(WTF::holds_alternative<AST::ConstantExpression>(nativeTypeDeclaration.typeArguments()[1]));
    ASSERT(WTF::holds_alternative<AST::ConstantExpression>(nativeTypeDeclaration.typeArguments()[2]));
    return true;
}

bool Intrinsics::addFullTexture(AST::NativeTypeDeclaration& nativeTypeDeclaration, AST::TypeReference& innerType)
{
    auto textureTypeIndex = std::find(m_textureTypeNames, m_textureTypeNames + WTF_ARRAY_LENGTH(m_textureTypeNames), nativeTypeDeclaration.name()) - m_textureTypeNames;
    if (textureTypeIndex == WTF_ARRAY_LENGTH(m_textureTypeNames))
        return false;

    unsigned innerTypeIndex = WTF_ARRAY_LENGTH(m_textureInnerTypeNames);
    unsigned vectorLength;
    for (unsigned i = 0; i < WTF_ARRAY_LENGTH(m_textureInnerTypeNames); ++i) {
        if (innerType.name().startsWith(m_textureInnerTypeNames[i])) {
            innerTypeIndex = i;
            if (innerType.name() == m_textureInnerTypeNames[i])
                vectorLength = 1;
            else {
                ASSERT(innerType.name().length() == strlen(m_textureInnerTypeNames[i]) + 1);
                ASSERT(innerType.name()[innerType.name().length() - 1] == '2'
                    || innerType.name()[innerType.name().length() - 1] == '3'
                    || innerType.name()[innerType.name().length() - 1] == '4');
                vectorLength = innerType.name()[innerType.name().length() - 1] - '0';
            }
        }
    }
    ASSERT(innerTypeIndex != WTF_ARRAY_LENGTH(m_textureInnerTypeNames));
    nativeTypeDeclaration.setIsTexture();
    nativeTypeDeclaration.setIsOpaqueType();
    if (nativeTypeDeclaration.name() == "Texture1DArray" || nativeTypeDeclaration.name() == "RWTexture1DArray" || nativeTypeDeclaration.name() == "Texture2DArray" || nativeTypeDeclaration.name() == "RWTexture2DArray")
        nativeTypeDeclaration.setIsTextureArray();
    if (nativeTypeDeclaration.name() == "RWTexture1D" || nativeTypeDeclaration.name() == "RWTexture2D" || nativeTypeDeclaration.name() == "RWTexture3D" || nativeTypeDeclaration.name() == "RWTexture1DArray" || nativeTypeDeclaration.name() == "RWTexture2DArray")
        nativeTypeDeclaration.setIsWritableTexture();
    if (nativeTypeDeclaration.name() == "Texture1D" || nativeTypeDeclaration.name() == "RWTexture1D" || nativeTypeDeclaration.name() == "Texture1DArray" || nativeTypeDeclaration.name() == "RWTexture1DArray")
        nativeTypeDeclaration.setTextureDimension(1);
    if (nativeTypeDeclaration.name() == "Texture2D" || nativeTypeDeclaration.name() == "RWTexture2D" || nativeTypeDeclaration.name() == "TextureCube" || nativeTypeDeclaration.name() == "Texture2DArray" || nativeTypeDeclaration.name() == "RWTexture2DArray")
        nativeTypeDeclaration.setTextureDimension(2);
    if (nativeTypeDeclaration.name() == "Texture3D" || nativeTypeDeclaration.name() == "RWTexture3D")
        nativeTypeDeclaration.setTextureDimension(3);
    if (nativeTypeDeclaration.name() == "TextureCube")
        nativeTypeDeclaration.setIsCubeTexture();
    m_fullTextures[textureTypeIndex][innerTypeIndex][vectorLength - 1] = &nativeTypeDeclaration;
    return true;
}

void Intrinsics::addDepthTexture(AST::NativeTypeDeclaration& nativeTypeDeclaration, AST::TypeReference& innerType)
{
    AST::NativeTypeDeclaration** texture = nullptr;
    if (nativeTypeDeclaration.name() == "TextureDepth2D")
        texture = m_textureDepth2D;
    else if (nativeTypeDeclaration.name() == "TextureDepth2DArray")
        texture = m_textureDepth2DArray;
    else {
        ASSERT(nativeTypeDeclaration.name() == "TextureDepthCube");
        texture = m_textureDepthCube;
    }
    auto innerTypeIndex = std::find(m_depthTextureInnerTypes, m_depthTextureInnerTypes + WTF_ARRAY_LENGTH(m_depthTextureInnerTypes), innerType.name()) - m_depthTextureInnerTypes;
    ASSERT(innerTypeIndex != WTF_ARRAY_LENGTH(m_depthTextureInnerTypes));
    nativeTypeDeclaration.setIsTexture();
    nativeTypeDeclaration.setIsOpaqueType();
    if (texture == m_textureDepth2DArray)
        nativeTypeDeclaration.setIsTextureArray();
    if (texture == m_textureDepthCube)
        nativeTypeDeclaration.setIsCubeTexture();
    nativeTypeDeclaration.setTextureDimension(2);
    nativeTypeDeclaration.setIsDepthTexture();
    texture[innerTypeIndex] = &nativeTypeDeclaration;
}

void Intrinsics::addTexture(AST::NativeTypeDeclaration& nativeTypeDeclaration)
{
    ASSERT(nativeTypeDeclaration.typeArguments().size() == 1);
    ASSERT(WTF::holds_alternative<Ref<AST::TypeReference>>(nativeTypeDeclaration.typeArguments()[0]));
    auto& innerType = static_cast<AST::TypeReference&>(WTF::get<Ref<AST::TypeReference>>(nativeTypeDeclaration.typeArguments()[0]));
    ASSERT(!innerType.typeArguments().size());
    if (addFullTexture(nativeTypeDeclaration, innerType)) {
        m_textureSet.add(&nativeTypeDeclaration);
        return;
    }
    addDepthTexture(nativeTypeDeclaration, innerType);
    m_textureSet.add(&nativeTypeDeclaration);
}

void Intrinsics::add(AST::NativeTypeDeclaration& nativeTypeDeclaration)
{
    if (addPrimitive(nativeTypeDeclaration))
        return;
    if (addVector(nativeTypeDeclaration))
        return;
    if (addMatrix(nativeTypeDeclaration))
        return;
    addTexture(nativeTypeDeclaration);
}

} // namespace WHLSL

} // namespace WebCore

#endif // ENABLE(WEBGPU)
