// 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;
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);
}

// TODO(https://crbug.com/dawn/1381) Remove when namespaces are not indented.
// NOLINTNEXTLINE(readability/namespace)
}  // namespace
}  // namespace dawn::native
