// 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::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<&Server::OnRequestDeviceCallback>,
                                    userdata.release());
        return true;
    }

    void Server::OnRequestDeviceCallback(RequestDeviceUserdata* data,
                                         WGPURequestDeviceStatus status,
                                         WGPUDevice device,
                                         const char* message) {
        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
