// Copyright 2018 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 "common/Result.h"

namespace {

template<typename T, typename E>
void TestError(Result<T, E>* result, E expectedError) {
    ASSERT_TRUE(result->IsError());
    ASSERT_FALSE(result->IsSuccess());

    E storedError = result->AcquireError();
    ASSERT_EQ(storedError, expectedError);
}

template<typename T, typename E>
void TestSuccess(Result<T, E>* result, T expectedSuccess) {
    ASSERT_FALSE(result->IsError());
    ASSERT_TRUE(result->IsSuccess());

    T storedSuccess = result->AcquireSuccess();
    ASSERT_EQ(storedSuccess, expectedSuccess);
}

static int dummyError = 0xbeef;
static float dummySuccess = 42.0f;
static const float dummyConstSuccess = 42.0f;

// Result<void, E*>

// Test constructing an error Result<void, E*>
TEST(ResultOnlyPointerError, ConstructingError) {
    Result<void, int*> result(&dummyError);
    TestError(&result, &dummyError);
}

// Test moving an error Result<void, E*>
TEST(ResultOnlyPointerError, MovingError) {
    Result<void, int*> result(&dummyError);
    Result<void, int*> movedResult(std::move(result));
    TestError(&movedResult, &dummyError);
}

// Test returning an error Result<void, E*>
TEST(ResultOnlyPointerError, ReturningError) {
    auto CreateError = []() -> Result<void, int*> {
        return {&dummyError};
    };

    Result<void, int*> result = CreateError();
    TestError(&result, &dummyError);
}

// Test constructing a success Result<void, E*>
TEST(ResultOnlyPointerError, ConstructingSuccess) {
    Result<void, int*> result;
    ASSERT_TRUE(result.IsSuccess());
    ASSERT_FALSE(result.IsError());
}

// Test moving a success Result<void, E*>
TEST(ResultOnlyPointerError, MovingSuccess) {
    Result<void, int*> result;
    Result<void, int*> movedResult(std::move(result));
    ASSERT_TRUE(movedResult.IsSuccess());
    ASSERT_FALSE(movedResult.IsError());
}

// Test returning a success Result<void, E*>
TEST(ResultOnlyPointerError, ReturningSuccess) {
    auto CreateError = []() -> Result<void, int*> {
        return {};
    };

    Result<void, int*> result = CreateError();
    ASSERT_TRUE(result.IsSuccess());
    ASSERT_FALSE(result.IsError());
}

// Result<T*, E*>

// Test constructing an error Result<T*, E*>
TEST(ResultBothPointer, ConstructingError) {
    Result<float*, int*> result(&dummyError);
    TestError(&result, &dummyError);
}

// Test moving an error Result<T*, E*>
TEST(ResultBothPointer, MovingError) {
    Result<float*, int*> result(&dummyError);
    Result<float*, int*> movedResult(std::move(result));
    TestError(&movedResult, &dummyError);
}

// Test returning an error Result<T*, E*>
TEST(ResultBothPointer, ReturningError) {
    auto CreateError = []() -> Result<float*, int*> {
        return {&dummyError};
    };

    Result<float*, int*> result = CreateError();
    TestError(&result, &dummyError);
}

// Test constructing a success Result<T*, E*>
TEST(ResultBothPointer, ConstructingSuccess) {
    Result<float*, int*> result(&dummySuccess);
    TestSuccess(&result, &dummySuccess);
}

// Test moving a success Result<T*, E*>
TEST(ResultBothPointer, MovingSuccess) {
    Result<float*, int*> result(&dummySuccess);
    Result<float*, int*> movedResult(std::move(result));
    TestSuccess(&movedResult, &dummySuccess);
}

// Test returning a success Result<T*, E*>
TEST(ResultBothPointer, ReturningSuccess) {
    auto CreateSuccess = []() -> Result<float*, int*> {
        return {&dummySuccess};
    };

    Result<float*, int*> result = CreateSuccess();
    TestSuccess(&result, &dummySuccess);
}

// Tests converting from a Result<TChild*, E*>
TEST(ResultBothPointer, ConversionFromChildClass) {
    struct T {
        int a;
    };
    struct TChild : T {};

    TChild child;
    T* childAsT = &child;
    {
        Result<T*, int*> result(&child);
        TestSuccess(&result, childAsT);
    }
    {
        Result<TChild*, int*> resultChild(&child);
        Result<T*, int*> result(std::move(resultChild));
        TestSuccess(&result, childAsT);
    }
    {
        Result<TChild*, int*> resultChild(&child);
        Result<T*, int*> result = std::move(resultChild);
        TestSuccess(&result, childAsT);
    }
}

// Result<const T*, E*>

// Test constructing an error Result<const T*, E*>
TEST(ResultBothPointerWithConstResult, ConstructingError) {
    Result<const float*, int*> result(&dummyError);
    TestError(&result, &dummyError);
}

// Test moving an error Result<const T*, E*>
TEST(ResultBothPointerWithConstResult, MovingError) {
    Result<const float*, int*> result(&dummyError);
    Result<const float*, int*> movedResult(std::move(result));
    TestError(&movedResult, &dummyError);
}

// Test returning an error Result<const T*, E*>
TEST(ResultBothPointerWithConstResult, ReturningError) {
    auto CreateError = []() -> Result<const float*, int*> { return {&dummyError}; };

    Result<const float*, int*> result = CreateError();
    TestError(&result, &dummyError);
}

// Test constructing a success Result<const T*, E*>
TEST(ResultBothPointerWithConstResult, ConstructingSuccess) {
    Result<const float*, int*> result(&dummyConstSuccess);
    TestSuccess(&result, &dummyConstSuccess);
}

// Test moving a success Result<const T*, E*>
TEST(ResultBothPointerWithConstResult, MovingSuccess) {
    Result<const float*, int*> result(&dummyConstSuccess);
    Result<const float*, int*> movedResult(std::move(result));
    TestSuccess(&movedResult, &dummyConstSuccess);
}

// Test returning a success Result<const T*, E*>
TEST(ResultBothPointerWithConstResult, ReturningSuccess) {
    auto CreateSuccess = []() -> Result<const float*, int*> { return {&dummyConstSuccess}; };

    Result<const float*, int*> result = CreateSuccess();
    TestSuccess(&result, &dummyConstSuccess);
}

// Result<T, E>

// Test constructing an error Result<T, E>
TEST(ResultGeneric, ConstructingError) {
    Result<std::vector<float>, int*> result(&dummyError);
    TestError(&result, &dummyError);
}

// Test moving an error Result<T, E>
TEST(ResultGeneric, MovingError) {
    Result<std::vector<float>, int*> result(&dummyError);
    Result<std::vector<float>, int*> movedResult(std::move(result));
    TestError(&movedResult, &dummyError);
}

// Test returning an error Result<T, E>
TEST(ResultGeneric, ReturningError) {
    auto CreateError = []() -> Result<std::vector<float>, int*> {
        return {&dummyError};
    };

    Result<std::vector<float>, int*> result = CreateError();
    TestError(&result, &dummyError);
}

// Test constructing a success Result<T, E>
TEST(ResultGeneric, ConstructingSuccess) {
    Result<std::vector<float>, int*> result({1.0f});
    TestSuccess(&result, {1.0f});
}

// Test moving a success Result<T, E>
TEST(ResultGeneric, MovingSuccess) {
    Result<std::vector<float>, int*> result({1.0f});
    Result<std::vector<float>, int*> movedResult(std::move(result));
    TestSuccess(&movedResult, {1.0f});
}

// Test returning a success Result<T, E>
TEST(ResultGeneric, ReturningSuccess) {
    auto CreateSuccess = []() -> Result<std::vector<float>, int*> {
        return {{1.0f}};
    };

    Result<std::vector<float>, int*> result = CreateSuccess();
    TestSuccess(&result, {1.0f});
}

}  // anonymous namespace
