// Copyright 2017 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 <gtest/gtest.h>

#include "dawn/webgpu_cpp.h"

class Object : public wgpu::ObjectBase<Object, int*> {
  public:
    using ObjectBase::ObjectBase;
    using ObjectBase::operator=;

    static void WGPUReference(int* handle) {
        ASSERT_LE(0, *handle);
        *handle += 1;
    }
    static void WGPURelease(int* handle) {
        ASSERT_LT(0, *handle);
        *handle -= 1;
    }
};

// Test that creating an C++ object from a C object takes a ref.
// Also test that the C++ object destructor removes a ref.
TEST(ObjectBase, CTypeConstructor) {
    int refcount = 1;
    {
        Object obj(&refcount);
        ASSERT_EQ(2, refcount);
    }
    ASSERT_EQ(1, refcount);
}

// Test consuming a C object into a C++ object doesn't take a ref.
TEST(ObjectBase, AcquireConstruction) {
    int refcount = 1;
    {
        Object object = Object::Acquire(&refcount);
        ASSERT_EQ(1, refcount);
    }
    ASSERT_EQ(0, refcount);
}

// Test .Get().
TEST(ObjectBase, Get) {
    int refcount = 1;
    {
        Object obj1(&refcount);

        ASSERT_EQ(2, refcount);
        ASSERT_EQ(&refcount, obj1.Get());
    }
    ASSERT_EQ(1, refcount);
}

// Test that Release consumes the C++ object into a C object and doesn't release
TEST(ObjectBase, Release) {
    int refcount = 1;
    {
        Object obj(&refcount);
        ASSERT_EQ(2, refcount);

        ASSERT_EQ(&refcount, obj.Release());
        ASSERT_EQ(nullptr, obj.Get());
        ASSERT_EQ(2, refcount);
    }
    ASSERT_EQ(2, refcount);
}

// Test using C++ objects in conditions
TEST(ObjectBase, OperatorBool) {
    int refcount = 1;
    Object trueObj(&refcount);
    Object falseObj;

    if (falseObj || !trueObj) {
        ASSERT_TRUE(false);
    }
}

// Test the copy constructor of C++ objects
TEST(ObjectBase, CopyConstructor) {
    int refcount = 1;

    Object source(&refcount);
    Object destination(source);

    ASSERT_EQ(source.Get(), &refcount);
    ASSERT_EQ(destination.Get(), &refcount);
    ASSERT_EQ(3, refcount);

    destination = Object();
    ASSERT_EQ(refcount, 2);
}

// Test the copy assignment of C++ objects
TEST(ObjectBase, CopyAssignment) {
    int refcount = 1;
    Object source(&refcount);

    Object destination;
    destination = source;

    ASSERT_EQ(source.Get(), &refcount);
    ASSERT_EQ(destination.Get(), &refcount);
    ASSERT_EQ(3, refcount);

    destination = Object();
    ASSERT_EQ(refcount, 2);
}

// Test the repeated copy assignment of C++ objects
TEST(ObjectBase, RepeatedCopyAssignment) {
    int refcount = 1;
    Object source(&refcount);

    Object destination;
    for (int i = 0; i < 10; i++) {
        destination = source;
    }

    ASSERT_EQ(source.Get(), &refcount);
    ASSERT_EQ(destination.Get(), &refcount);
    ASSERT_EQ(3, refcount);

    destination = Object();
    ASSERT_EQ(refcount, 2);
}

// Test the copy assignment of C++ objects onto themselves
TEST(ObjectBase, CopyAssignmentSelf) {
    int refcount = 1;

    Object obj(&refcount);

    // Fool the compiler to avoid a -Wself-assign-overload
    Object* objPtr = &obj;
    obj = *objPtr;

    ASSERT_EQ(obj.Get(), &refcount);
    ASSERT_EQ(refcount, 2);
}

// Test the move constructor of C++ objects
TEST(ObjectBase, MoveConstructor) {
    int refcount = 1;
    Object source(&refcount);
    Object destination(std::move(source));

    ASSERT_EQ(source.Get(), nullptr);
    ASSERT_EQ(destination.Get(), &refcount);
    ASSERT_EQ(2, refcount);

    destination = Object();
    ASSERT_EQ(refcount, 1);
}

// Test the move assignment of C++ objects
TEST(ObjectBase, MoveAssignment) {
    int refcount = 1;
    Object source(&refcount);

    Object destination;
    destination = std::move(source);

    ASSERT_EQ(source.Get(), nullptr);
    ASSERT_EQ(destination.Get(), &refcount);
    ASSERT_EQ(2, refcount);

    destination = Object();
    ASSERT_EQ(refcount, 1);
}

// Test the move assignment of C++ objects onto themselves
TEST(ObjectBase, MoveAssignmentSelf) {
    int refcount = 1;

    Object obj(&refcount);

    // Fool the compiler to avoid a -Wself-move
    Object* objPtr = &obj;
    obj = std::move(*objPtr);

    ASSERT_EQ(obj.Get(), &refcount);
    ASSERT_EQ(refcount, 2);
}

// Test the constructor using nullptr
TEST(ObjectBase, NullptrConstructor) {
    Object obj(nullptr);
    ASSERT_EQ(obj.Get(), nullptr);
}

// Test assigning nullptr to the object
TEST(ObjectBase, AssignNullptr) {
    int refcount = 1;

    Object obj(&refcount);
    ASSERT_EQ(refcount, 2);

    obj = nullptr;
    ASSERT_EQ(refcount, 1);
}
