// 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::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,
                                      WGPUDeviceLostReason reason,
                                      char const* message) {
        if (device == nullptr) {
            // The device might have been deleted or recreated so this isn't an error.
            return true;
        }
        device->HandleDeviceLost(reason, 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
