// Copyright 2021 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_wire/server/Server.h"

#include "dawn_wire/SupportedFeatures.h"

namespace dawn_wire { namespace server {

    bool Server::DoAdapterRequestDevice(ObjectId adapterId,
                                        uint64_t requestSerial,
                                        ObjectHandle deviceHandle,
                                        const WGPUDeviceDescriptor* descriptor) {
        auto* adapter = AdapterObjects().Get(adapterId);
        if (adapter == nullptr) {
            return false;
        }

        auto* resultData = DeviceObjects().Allocate(deviceHandle.id, AllocationState::Reserved);
        if (resultData == nullptr) {
            return false;
        }

        resultData->generation = deviceHandle.generation;

        auto userdata = MakeUserdata<RequestDeviceUserdata>();
        userdata->adapter = ObjectHandle{adapterId, adapter->generation};
        userdata->requestSerial = requestSerial;
        userdata->deviceObjectId = deviceHandle.id;

        mProcs.adapterRequestDevice(
            adapter->handle, descriptor,
            ForwardToServer<decltype(
                &Server::OnRequestDeviceCallback)>::Func<&Server::OnRequestDeviceCallback>(),
            userdata.release());
        return true;
    }

    void Server::OnRequestDeviceCallback(WGPURequestDeviceStatus status,
                                         WGPUDevice device,
                                         const char* message,
                                         RequestDeviceUserdata* data) {
        auto* deviceObject = DeviceObjects().Get(data->deviceObjectId, AllocationState::Reserved);
        // Should be impossible to fail. ObjectIds can't be freed by a destroy command until
        // they move from Reserved to Allocated, or if they are destroyed here.
        ASSERT(deviceObject != nullptr);

        ReturnAdapterRequestDeviceCallbackCmd cmd = {};
        cmd.adapter = data->adapter;
        cmd.requestSerial = data->requestSerial;
        cmd.status = status;
        cmd.message = message;

        if (status != WGPURequestDeviceStatus_Success) {
            // Free the ObjectId which will make it unusable.
            DeviceObjects().Free(data->deviceObjectId);
            ASSERT(device == nullptr);
            SerializeCommand(cmd);
            return;
        }

        std::vector<WGPUFeatureName> features;

        uint32_t featuresCount = mProcs.deviceEnumerateFeatures(device, nullptr);
        features.resize(featuresCount);
        mProcs.deviceEnumerateFeatures(device, features.data());

        // The client should only be able to request supported features, so all enumerated
        // features that were enabled must also be supported by the wire.
        // Note: We fail the callback here, instead of immediately upon receiving
        // the request to preserve callback ordering.
        for (WGPUFeatureName f : features) {
            if (!IsFeatureSupported(f)) {
                // Release the device.
                mProcs.deviceRelease(device);
                // Free the ObjectId which will make it unusable.
                DeviceObjects().Free(data->deviceObjectId);

                cmd.status = WGPURequestDeviceStatus_Error;
                cmd.message = "Requested feature not supported.";
                SerializeCommand(cmd);
                return;
            }
        }

        cmd.featuresCount = features.size();
        cmd.features = features.data();

        WGPUSupportedLimits limits = {};
        mProcs.deviceGetLimits(device, &limits);
        cmd.limits = &limits;

        // Assign the handle and allocated status if the device is created successfully.
        deviceObject->state = AllocationState::Allocated;
        deviceObject->handle = device;
        SetForwardingDeviceCallbacks(deviceObject);

        SerializeCommand(cmd);
    }

}}  // namespace dawn_wire::server
