// Copyright 2019 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 "dawn_native/ErrorScope.h"

#include "common/Assert.h"

namespace dawn_native {

    namespace {

        wgpu::ErrorType ErrorFilterToErrorType(wgpu::ErrorFilter filter) {
            switch (filter) {
                case wgpu::ErrorFilter::Validation:
                    return wgpu::ErrorType::Validation;
                case wgpu::ErrorFilter::OutOfMemory:
                    return wgpu::ErrorType::OutOfMemory;
            }
            UNREACHABLE();
        }

    }  // namespace

    ErrorScope::ErrorScope(wgpu::ErrorFilter errorFilter)
        : mMatchedErrorType(ErrorFilterToErrorType(errorFilter)) {
    }

    wgpu::ErrorType ErrorScope::GetErrorType() const {
        return mCapturedError;
    }

    const char* ErrorScope::GetErrorMessage() const {
        return mErrorMessage.c_str();
    }

    void ErrorScopeStack::Push(wgpu::ErrorFilter filter) {
        mScopes.push_back(ErrorScope(filter));
    }

    ErrorScope ErrorScopeStack::Pop() {
        ASSERT(!mScopes.empty());
        ErrorScope scope = std::move(mScopes.back());
        mScopes.pop_back();
        return scope;
    }

    bool ErrorScopeStack::Empty() const {
        return mScopes.empty();
    }

    bool ErrorScopeStack::HandleError(wgpu::ErrorType type, const char* message) {
        for (auto it = mScopes.rbegin(); it != mScopes.rend(); ++it) {
            if (it->mMatchedErrorType != type) {
                // Error filter does not match. Move on to the next scope.
                continue;
            }

            // Filter matches.
            // Record the error if the scope doesn't have one yet.
            if (it->mCapturedError == wgpu::ErrorType::NoError) {
                it->mCapturedError = type;
                it->mErrorMessage = message;
            }

            if (type == wgpu::ErrorType::DeviceLost) {
                if (it->mCapturedError != wgpu::ErrorType::DeviceLost) {
                    // DeviceLost overrides any other error that is not a DeviceLost.
                    it->mCapturedError = type;
                    it->mErrorMessage = message;
                }
            } else {
                // Errors that are not device lost are captured and stop propogating.
                return true;
            }
        }

        // The error was not captured.
        return false;
    }

}  // namespace dawn_native
