/*
 *
 * Copyright (c) 2018 Google Inc.
 *
 * 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 <lib/fdio/directory.h>
#include <limits.h>
#include <zircon/device/vfs.h>

#include "loader.h"
#include "loader_service.h"

typedef VkResult(VKAPI_PTR *PFN_vkOpenInNamespaceAddr)(const char *pName, uint32_t handle);
typedef PFN_vkVoidFunction(VKAPI_PTR *PFN_vkInitializeOpenInNamespaceCallbackAddr)(PFN_vkOpenInNamespaceAddr);

VKAPI_ATTR static VkResult VKAPI_CALL loader_fdio_open_in_namespace(const char *pName, uint32_t handle) {
    const struct GpuDeviceMappings *mapping = NULL;
    static const char kGpuDevicePrefix[] = "/loader-gpu-devices";
    zx_status_t status;
    // Compare only the prefix.
    if (strncmp(pName, kGpuDevicePrefix, sizeof(kGpuDevicePrefix) - 1) == 0) {
        // Accesses to subpaths of /loader-gpu-devices should be redirected through the devicefs exposed by the loader service.
        // See README.md in this directory for details.
        zx_handle_t device_fs = get_device_fs();
        if (!device_fs) {
            return VK_ERROR_INITIALIZATION_FAILED;
        }
        size_t prefix_size = strlen(kGpuDevicePrefix);
        size_t name_size = strlen(pName);
        if (prefix_size == name_size) {
            status = fdio_open_at(device_fs, ".", ZX_FS_RIGHT_READABLE, handle);
        } else {
            const char *new_name = pName + prefix_size;
            if (new_name[0] != '/') {
                // Name must be "/loader-gpu-devices/", or that's a bug.
                return VK_ERROR_INITIALIZATION_FAILED;
            }
            status = fdio_open_at(device_fs, new_name, ZX_FS_RIGHT_READABLE, handle);
        }
    } else {
        // fdio_service_connect specifies READ+WRITE, which fails for read-only files
        status = fdio_open(pName, ZX_FS_RIGHT_READABLE, handle);
    }

    if (status == ZX_OK) {
        return VK_SUCCESS;
    } else {
        loader_log(NULL, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, "Failed to open in namespace %s - error %d", pName, status);
        return VK_ERROR_INITIALIZATION_FAILED;
    }
}

void loader_initialize_icd_services(loader_platform_dl_handle handle) {
    PFN_vkInitializeOpenInNamespaceCallbackAddr fp_initialize_open_in_namespace_callback_addr;

    fp_initialize_open_in_namespace_callback_addr = reinterpret_cast<PFN_vkInitializeOpenInNamespaceCallbackAddr>(
        loader_platform_get_proc_address(handle, "vk_icdInitializeOpenInNamespaceCallback"));
    if (fp_initialize_open_in_namespace_callback_addr) {
        fp_initialize_open_in_namespace_callback_addr(&loader_fdio_open_in_namespace);
        // ICD isn't required to expose this entrypoint.
        return;
    }
}
