// 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 "common/Assert.h"
#include "dawn_wire/client/Client.h"
#include "dawn_wire/client/Device.h"

#include <limits>

namespace dawn_wire { namespace client {

    bool Client::DoDeviceUncapturedErrorCallback(Device* device,
                                                 WGPUErrorType errorType,
                                                 const char* message) {
        switch (errorType) {
            case WGPUErrorType_NoError:
            case WGPUErrorType_Validation:
            case WGPUErrorType_OutOfMemory:
            case WGPUErrorType_Unknown:
            case WGPUErrorType_DeviceLost:
                break;
            default:
                return false;
        }
        if (device == nullptr) {
            // The device might have been deleted or recreated so this isn't an error.
            return true;
        }
        device->HandleError(errorType, message);
        return true;
    }

    bool Client::DoDeviceLoggingCallback(Device* device,
                                         WGPULoggingType loggingType,
                                         const char* message) {
        if (device == nullptr) {
            // The device might have been deleted or recreated so this isn't an error.
            return true;
        }
        device->HandleLogging(loggingType, message);
        return true;
    }

    bool Client::DoDeviceLostCallback(Device* device, char const* message) {
        if (device == nullptr) {
            // The device might have been deleted or recreated so this isn't an error.
            return true;
        }
        device->HandleDeviceLost(message);
        return true;
    }

    bool Client::DoDevicePopErrorScopeCallback(Device* device,
                                               uint64_t requestSerial,
                                               WGPUErrorType errorType,
                                               const char* message) {
        if (device == nullptr) {
            // The device might have been deleted or recreated so this isn't an error.
            return true;
        }
        return device->OnPopErrorScopeCallback(requestSerial, errorType, message);
    }

    bool Client::DoBufferMapAsyncCallback(Buffer* buffer,
                                          uint64_t requestSerial,
                                          uint32_t status,
                                          uint64_t readDataUpdateInfoLength,
                                          const uint8_t* readDataUpdateInfo) {
        // The buffer might have been deleted or recreated so this isn't an error.
        if (buffer == nullptr) {
            return true;
        }
        return buffer->OnMapAsyncCallback(requestSerial, status, readDataUpdateInfoLength,
                                          readDataUpdateInfo);
    }

    bool Client::DoQueueWorkDoneCallback(Queue* queue,
                                         uint64_t requestSerial,
                                         WGPUQueueWorkDoneStatus status) {
        // The queue might have been deleted or recreated so this isn't an error.
        if (queue == nullptr) {
            return true;
        }
        return queue->OnWorkDoneCallback(requestSerial, status);
    }

    bool Client::DoDeviceCreateComputePipelineAsyncCallback(Device* device,
                                                            uint64_t requestSerial,
                                                            WGPUCreatePipelineAsyncStatus status,
                                                            const char* message) {
        // The device might have been deleted or recreated so this isn't an error.
        if (device == nullptr) {
            return true;
        }
        return device->OnCreateComputePipelineAsyncCallback(requestSerial, status, message);
    }

    bool Client::DoDeviceCreateRenderPipelineAsyncCallback(Device* device,
                                                           uint64_t requestSerial,
                                                           WGPUCreatePipelineAsyncStatus status,
                                                           const char* message) {
        // The device might have been deleted or recreated so this isn't an error.
        if (device == nullptr) {
            return true;
        }
        return device->OnCreateRenderPipelineAsyncCallback(requestSerial, status, message);
    }

    bool Client::DoShaderModuleGetCompilationInfoCallback(ShaderModule* shaderModule,
                                                          uint64_t requestSerial,
                                                          WGPUCompilationInfoRequestStatus status,
                                                          const WGPUCompilationInfo* info) {
        // The shader module might have been deleted or recreated so this isn't an error.
        if (shaderModule == nullptr) {
            return true;
        }
        return shaderModule->GetCompilationInfoCallback(requestSerial, status, info);
    }

}}  // namespace dawn_wire::client
