// 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 <memory>

#include "dawn/native/Error.h"
#include "dawn/native/ErrorData.h"
#include "gtest/gtest.h"

namespace dawn::native {
namespace {

int placeholderSuccess = 0xbeef;
constexpr const char* placeholderErrorMessage = "I am an error message :3";

// Check returning a success MaybeError with {};
TEST(ErrorTests, Error_Success) {
    auto ReturnSuccess = []() -> MaybeError { return {}; };

    MaybeError result = ReturnSuccess();
    ASSERT_TRUE(result.IsSuccess());
}

// Check returning an error MaybeError with "return DAWN_VALIDATION_ERROR"
TEST(ErrorTests, Error_Error) {
    auto ReturnError = []() -> MaybeError {
        return DAWN_VALIDATION_ERROR(placeholderErrorMessage);
    };

    MaybeError result = ReturnError();
    ASSERT_TRUE(result.IsError());

    std::unique_ptr<ErrorData> errorData = result.AcquireError();
    ASSERT_EQ(errorData->GetMessage(), placeholderErrorMessage);
}

// Check returning a success ResultOrError with an implicit conversion
TEST(ErrorTests, ResultOrError_Success) {
    auto ReturnSuccess = []() -> ResultOrError<int*> { return &placeholderSuccess; };

    ResultOrError<int*> result = ReturnSuccess();
    ASSERT_TRUE(result.IsSuccess());
    ASSERT_EQ(result.AcquireSuccess(), &placeholderSuccess);
}

// Check returning an error ResultOrError with "return DAWN_VALIDATION_ERROR"
TEST(ErrorTests, ResultOrError_Error) {
    auto ReturnError = []() -> ResultOrError<int*> {
        return DAWN_VALIDATION_ERROR(placeholderErrorMessage);
    };

    ResultOrError<int*> result = ReturnError();
    ASSERT_TRUE(result.IsError());

    std::unique_ptr<ErrorData> errorData = result.AcquireError();
    ASSERT_EQ(errorData->GetMessage(), placeholderErrorMessage);
}

// Check DAWN_TRY handles successes correctly.
TEST(ErrorTests, TRY_Success) {
    auto ReturnSuccess = []() -> MaybeError { return {}; };

    // We need to check that DAWN_TRY doesn't return on successes
    bool tryReturned = true;

    auto Try = [ReturnSuccess, &tryReturned]() -> MaybeError {
        DAWN_TRY(ReturnSuccess());
        tryReturned = false;
        return {};
    };

    MaybeError result = Try();
    ASSERT_TRUE(result.IsSuccess());
    ASSERT_FALSE(tryReturned);
}

// Check DAWN_TRY handles errors correctly.
TEST(ErrorTests, TRY_Error) {
    auto ReturnError = []() -> MaybeError {
        return DAWN_VALIDATION_ERROR(placeholderErrorMessage);
    };

    auto Try = [ReturnError]() -> MaybeError {
        DAWN_TRY(ReturnError());
        // DAWN_TRY should return before this point
        EXPECT_FALSE(true);
        return {};
    };

    MaybeError result = Try();
    ASSERT_TRUE(result.IsError());

    std::unique_ptr<ErrorData> errorData = result.AcquireError();
    ASSERT_EQ(errorData->GetMessage(), placeholderErrorMessage);
}

// Check DAWN_TRY adds to the backtrace.
TEST(ErrorTests, TRY_AddsToBacktrace) {
    auto ReturnError = []() -> MaybeError {
        return DAWN_VALIDATION_ERROR(placeholderErrorMessage);
    };

    auto SingleTry = [ReturnError]() -> MaybeError {
        DAWN_TRY(ReturnError());
        return {};
    };

    auto DoubleTry = [SingleTry]() -> MaybeError {
        DAWN_TRY(SingleTry());
        return {};
    };

    MaybeError singleResult = SingleTry();
    ASSERT_TRUE(singleResult.IsError());

    MaybeError doubleResult = DoubleTry();
    ASSERT_TRUE(doubleResult.IsError());

    std::unique_ptr<ErrorData> singleData = singleResult.AcquireError();
    std::unique_ptr<ErrorData> doubleData = doubleResult.AcquireError();

    ASSERT_EQ(singleData->GetBacktrace().size() + 1, doubleData->GetBacktrace().size());
}

// Check DAWN_TRY_ASSIGN handles successes correctly.
TEST(ErrorTests, TRY_RESULT_Success) {
    auto ReturnSuccess = []() -> ResultOrError<int*> { return &placeholderSuccess; };

    // We need to check that DAWN_TRY doesn't return on successes
    bool tryReturned = true;

    auto Try = [ReturnSuccess, &tryReturned]() -> ResultOrError<int*> {
        int* result = nullptr;
        DAWN_TRY_ASSIGN(result, ReturnSuccess());
        tryReturned = false;

        EXPECT_EQ(result, &placeholderSuccess);
        return result;
    };

    ResultOrError<int*> result = Try();
    ASSERT_TRUE(result.IsSuccess());
    ASSERT_FALSE(tryReturned);
    ASSERT_EQ(result.AcquireSuccess(), &placeholderSuccess);
}

// Check DAWN_TRY_ASSIGN handles errors correctly.
TEST(ErrorTests, TRY_RESULT_Error) {
    auto ReturnError = []() -> ResultOrError<int*> {
        return DAWN_VALIDATION_ERROR(placeholderErrorMessage);
    };

    auto Try = [ReturnError]() -> ResultOrError<int*> {
        int* result = nullptr;
        DAWN_TRY_ASSIGN(result, ReturnError());
        DAWN_UNUSED(result);

        // DAWN_TRY should return before this point
        EXPECT_FALSE(true);
        return &placeholderSuccess;
    };

    ResultOrError<int*> result = Try();
    ASSERT_TRUE(result.IsError());

    std::unique_ptr<ErrorData> errorData = result.AcquireError();
    ASSERT_EQ(errorData->GetMessage(), placeholderErrorMessage);
}

// Check DAWN_TRY_ASSIGN adds to the backtrace.
TEST(ErrorTests, TRY_RESULT_AddsToBacktrace) {
    auto ReturnError = []() -> ResultOrError<int*> {
        return DAWN_VALIDATION_ERROR(placeholderErrorMessage);
    };

    auto SingleTry = [ReturnError]() -> ResultOrError<int*> {
        DAWN_TRY(ReturnError());
        return &placeholderSuccess;
    };

    auto DoubleTry = [SingleTry]() -> ResultOrError<int*> {
        DAWN_TRY(SingleTry());
        return &placeholderSuccess;
    };

    ResultOrError<int*> singleResult = SingleTry();
    ASSERT_TRUE(singleResult.IsError());

    ResultOrError<int*> doubleResult = DoubleTry();
    ASSERT_TRUE(doubleResult.IsError());

    std::unique_ptr<ErrorData> singleData = singleResult.AcquireError();
    std::unique_ptr<ErrorData> doubleData = doubleResult.AcquireError();

    ASSERT_EQ(singleData->GetBacktrace().size() + 1, doubleData->GetBacktrace().size());
}

// Check a ResultOrError can be DAWN_TRY_ASSIGNED in a function that returns an Error
TEST(ErrorTests, TRY_RESULT_ConversionToError) {
    auto ReturnError = []() -> ResultOrError<int*> {
        return DAWN_VALIDATION_ERROR(placeholderErrorMessage);
    };

    auto Try = [ReturnError]() -> MaybeError {
        int* result = nullptr;
        DAWN_TRY_ASSIGN(result, ReturnError());
        DAWN_UNUSED(result);

        return {};
    };

    MaybeError result = Try();
    ASSERT_TRUE(result.IsError());

    std::unique_ptr<ErrorData> errorData = result.AcquireError();
    ASSERT_EQ(errorData->GetMessage(), placeholderErrorMessage);
}

// Check a ResultOrError can be DAWN_TRY_ASSIGNED in a function that returns an Error
// Version without Result<E*, T*>
TEST(ErrorTests, TRY_RESULT_ConversionToErrorNonPointer) {
    auto ReturnError = []() -> ResultOrError<int> {
        return DAWN_VALIDATION_ERROR(placeholderErrorMessage);
    };

    auto Try = [ReturnError]() -> MaybeError {
        int result = 0;
        DAWN_TRY_ASSIGN(result, ReturnError());
        DAWN_UNUSED(result);

        return {};
    };

    MaybeError result = Try();
    ASSERT_TRUE(result.IsError());

    std::unique_ptr<ErrorData> errorData = result.AcquireError();
    ASSERT_EQ(errorData->GetMessage(), placeholderErrorMessage);
}

// Check DAWN_TRY_ASSIGN handles successes correctly.
TEST(ErrorTests, TRY_RESULT_CLEANUP_Success) {
    auto ReturnSuccess = []() -> ResultOrError<int*> { return &placeholderSuccess; };

    // We need to check that DAWN_TRY_ASSIGN_WITH_CLEANUP doesn't return on successes and the
    // cleanup is not called.
    bool tryReturned = true;
    bool tryCleanup = false;

    auto Try = [ReturnSuccess, &tryReturned, &tryCleanup]() -> ResultOrError<int*> {
        int* result = nullptr;
        DAWN_TRY_ASSIGN_WITH_CLEANUP(result, ReturnSuccess(), { tryCleanup = true; });
        tryReturned = false;

        EXPECT_EQ(result, &placeholderSuccess);
        return result;
    };

    ResultOrError<int*> result = Try();
    ASSERT_TRUE(result.IsSuccess());
    ASSERT_FALSE(tryReturned);
    ASSERT_FALSE(tryCleanup);
    ASSERT_EQ(result.AcquireSuccess(), &placeholderSuccess);
}

// Check DAWN_TRY_ASSIGN handles cleanups.
TEST(ErrorTests, TRY_RESULT_CLEANUP_Cleanup) {
    auto ReturnError = []() -> ResultOrError<int*> {
        return DAWN_VALIDATION_ERROR(placeholderErrorMessage);
    };

    // We need to check that DAWN_TRY_ASSIGN_WITH_CLEANUP calls cleanup when error.
    bool tryCleanup = false;

    auto Try = [ReturnError, &tryCleanup]() -> ResultOrError<int*> {
        int* result = nullptr;
        DAWN_TRY_ASSIGN_WITH_CLEANUP(result, ReturnError(), { tryCleanup = true; });
        DAWN_UNUSED(result);

        // DAWN_TRY_ASSIGN_WITH_CLEANUP should return before this point
        EXPECT_FALSE(true);
        return &placeholderSuccess;
    };

    ResultOrError<int*> result = Try();
    ASSERT_TRUE(result.IsError());

    std::unique_ptr<ErrorData> errorData = result.AcquireError();
    ASSERT_EQ(errorData->GetMessage(), placeholderErrorMessage);
    ASSERT_TRUE(tryCleanup);
}

// Check DAWN_TRY_ASSIGN can override return value when needed.
TEST(ErrorTests, TRY_RESULT_CLEANUP_OverrideReturn) {
    auto ReturnError = []() -> ResultOrError<int*> {
        return DAWN_VALIDATION_ERROR(placeholderErrorMessage);
    };

    auto Try = [ReturnError]() -> bool {
        int* result = nullptr;
        DAWN_TRY_ASSIGN_WITH_CLEANUP(result, ReturnError(), {}, true);
        DAWN_UNUSED(result);

        // DAWN_TRY_ASSIGN_WITH_CLEANUP should return before this point
        EXPECT_FALSE(true);
        return false;
    };

    bool result = Try();
    ASSERT_TRUE(result);
}

// Check a MaybeError can be DAWN_TRIED in a function that returns an ResultOrError
// Check DAWN_TRY handles errors correctly.
TEST(ErrorTests, TRY_ConversionToErrorOrResult) {
    auto ReturnError = []() -> MaybeError {
        return DAWN_VALIDATION_ERROR(placeholderErrorMessage);
    };

    auto Try = [ReturnError]() -> ResultOrError<int*> {
        DAWN_TRY(ReturnError());
        return &placeholderSuccess;
    };

    ResultOrError<int*> result = Try();
    ASSERT_TRUE(result.IsError());

    std::unique_ptr<ErrorData> errorData = result.AcquireError();
    ASSERT_EQ(errorData->GetMessage(), placeholderErrorMessage);
}

// Check a MaybeError can be DAWN_TRIED in a function that returns an ResultOrError
// Check DAWN_TRY handles errors correctly. Version without Result<E*, T*>
TEST(ErrorTests, TRY_ConversionToErrorOrResultNonPointer) {
    auto ReturnError = []() -> MaybeError {
        return DAWN_VALIDATION_ERROR(placeholderErrorMessage);
    };

    auto Try = [ReturnError]() -> ResultOrError<int> {
        DAWN_TRY(ReturnError());
        return 42;
    };

    ResultOrError<int> result = Try();
    ASSERT_TRUE(result.IsError());

    std::unique_ptr<ErrorData> errorData = result.AcquireError();
    ASSERT_EQ(errorData->GetMessage(), placeholderErrorMessage);
}

}  // namespace
}  // namespace dawn::native
