/*
 * Copyright (c) 2022 The Khronos Group Inc.
 * Copyright (c) 2022 Valve Corporation
 * Copyright (c) 2022 LunarG, 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.
 *
 * Author: Jon Ashburn <jon@lunarg.com>
 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
 * Author: Mark Young <marky@lunarg.com>
 * Author: Lenny Komow <lenny@lunarg.com>
 * Author: Charles Giessen <charles@lunarg.com>
 */

#include "unknown_function_handling.h"

#include "allocation.h"
#include "log.h"

// Forward declarations
void *loader_get_dev_ext_trampoline(uint32_t index);
void *loader_get_phys_dev_ext_tramp(uint32_t index);
void *loader_get_phys_dev_ext_termin(uint32_t index);

// Device function handling

// Initialize device_ext dispatch table entry as follows:
// If dev == NULL find all logical devices created within this instance and
//  init the entry (given by idx) in the ext dispatch table.
// If dev != NULL only initialize the entry in the given dev's dispatch table.
// The initialization value is gotten by calling down the device chain with
// GDPA.
// If GDPA returns NULL then don't initialize the dispatch table entry.
void loader_init_dispatch_dev_ext_entry(struct loader_instance *inst, struct loader_device *dev, uint32_t idx, const char *funcName)

{
    void *gdpa_value;
    if (dev != NULL) {
        gdpa_value = dev->loader_dispatch.core_dispatch.GetDeviceProcAddr(dev->chain_device, funcName);
        if (gdpa_value != NULL) dev->loader_dispatch.ext_dispatch[idx] = (PFN_vkDevExt)gdpa_value;
    } else {
        for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) {
            struct loader_device *ldev = icd_term->logical_device_list;
            while (ldev) {
                gdpa_value = ldev->loader_dispatch.core_dispatch.GetDeviceProcAddr(ldev->chain_device, funcName);
                if (gdpa_value != NULL) ldev->loader_dispatch.ext_dispatch[idx] = (PFN_vkDevExt)gdpa_value;
                ldev = ldev->next;
            }
        }
    }
}

// Find all dev extension in the function names array  and initialize the dispatch table
// for dev  for each of those extension entrypoints found in function names array.
void loader_init_dispatch_dev_ext(struct loader_instance *inst, struct loader_device *dev) {
    for (uint32_t i = 0; i < MAX_NUM_UNKNOWN_EXTS; i++) {
        if (inst->dev_ext_disp_functions[i] != NULL)
            loader_init_dispatch_dev_ext_entry(inst, dev, i, inst->dev_ext_disp_functions[i]);
    }
}

bool loader_check_icds_for_dev_ext_address(struct loader_instance *inst, const char *funcName) {
    struct loader_icd_term *icd_term;
    icd_term = inst->icd_terms;
    while (NULL != icd_term) {
        if (icd_term->scanned_icd->GetInstanceProcAddr(icd_term->instance, funcName))
            // this icd supports funcName
            return true;
        icd_term = icd_term->next;
    }

    return false;
}

bool loader_check_layer_list_for_dev_ext_address(const struct loader_layer_list *const layers, const char *funcName) {
    // Iterate over the layers.
    for (uint32_t layer = 0; layer < layers->count; ++layer) {
        // Iterate over the extensions.
        const struct loader_device_extension_list *const extensions = &(layers->list[layer].device_extension_list);
        for (uint32_t extension = 0; extension < extensions->count; ++extension) {
            // Iterate over the entry points.
            const struct loader_dev_ext_props *const property = &(extensions->list[extension]);
            for (uint32_t entry = 0; entry < property->entrypoint_count; ++entry) {
                if (strcmp(property->entrypoints[entry], funcName) == 0) {
                    return true;
                }
            }
        }
    }

    return false;
}

void loader_free_dev_ext_table(struct loader_instance *inst) {
    for (uint32_t i = 0; i < inst->dev_ext_disp_function_count; i++) {
        loader_instance_heap_free(inst, inst->dev_ext_disp_functions[i]);
    }
    memset(inst->dev_ext_disp_functions, 0, sizeof(inst->dev_ext_disp_functions));
}

/*
 * This function returns generic trampoline code address for unknown entry points.
 * Presumably, these unknown entry points (as given by funcName) are device extension
 * entrypoints.
 * A function name array is used to keep a list of unknown entry points and their
 * mapping to the device extension dispatch table.
 * \returns
 * For a given entry point string (funcName), if an existing mapping is found the
 * trampoline address for that mapping is returned.
 * Otherwise, this unknown entry point has not been seen yet.
 * Next check if a layer or ICD supports it.
 * If so then a new entry in the function name array is added and that trampoline
 * address for the new entry is returned.
 * NULL is returned if the function name array is full or if no discovered layer or
 * ICD returns a non-NULL GetProcAddr for it.
 */
void *loader_dev_ext_gpa(struct loader_instance *inst, const char *funcName) {
    // Linearly look through already added functions to make sure we haven't seen it before
    // if we have, return the function at the index found
    for (uint32_t i = 0; i < inst->dev_ext_disp_function_count; i++) {
        if (inst->dev_ext_disp_functions[i] && !strcmp(inst->dev_ext_disp_functions[i], funcName))
            return loader_get_dev_ext_trampoline(i);
    }

    // Check if funcName is supported in either ICDs or a layer library
    if (!loader_check_icds_for_dev_ext_address(inst, funcName) &&
        !loader_check_layer_list_for_dev_ext_address(&inst->app_activated_layer_list, funcName)) {
        // if support found in layers continue on
        return NULL;
    }

    if (inst->dev_ext_disp_function_count >= MAX_NUM_UNKNOWN_EXTS) {
        loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0, "loader_dev_ext_gpa: Exhausted the unknown device function array!");
        return NULL;
    }

    // add found function to dev_ext_disp_functions;
    size_t funcName_len = strlen(funcName) + 1;
    inst->dev_ext_disp_functions[inst->dev_ext_disp_function_count] =
        (char *)loader_instance_heap_alloc(inst, funcName_len, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
    if (NULL == inst->dev_ext_disp_functions[inst->dev_ext_disp_function_count]) {
        // failed to allocate memory, return NULL
        return NULL;
    }
    strncpy(inst->dev_ext_disp_functions[inst->dev_ext_disp_function_count], funcName, funcName_len);
    // init any dev dispatch table entries as needed
    loader_init_dispatch_dev_ext_entry(inst, NULL, inst->dev_ext_disp_function_count, funcName);
    void *out_function = loader_get_dev_ext_trampoline(inst->dev_ext_disp_function_count);
    inst->dev_ext_disp_function_count++;
    return out_function;
}

// Physical Device function handling

bool loader_check_icds_for_phys_dev_ext_address(struct loader_instance *inst, const char *funcName) {
    struct loader_icd_term *icd_term;
    icd_term = inst->icd_terms;
    while (NULL != icd_term) {
        if (icd_term->scanned_icd->interface_version >= MIN_PHYS_DEV_EXTENSION_ICD_INTERFACE_VERSION &&
            icd_term->scanned_icd->GetPhysicalDeviceProcAddr(icd_term->instance, funcName))
            // this icd supports funcName
            return true;
        icd_term = icd_term->next;
    }

    return false;
}

bool loader_check_layer_list_for_phys_dev_ext_address(struct loader_instance *inst, const char *funcName) {
    struct loader_layer_properties *layer_prop_list = inst->expanded_activated_layer_list.list;
    for (uint32_t layer = 0; layer < inst->expanded_activated_layer_list.count; ++layer) {
        // If this layer supports the vk_layerGetPhysicalDeviceProcAddr, then call
        // it and see if it returns a valid pointer for this function name.
        if (layer_prop_list[layer].interface_version > 1) {
            const struct loader_layer_functions *const functions = &(layer_prop_list[layer].functions);
            if (NULL != functions->get_physical_device_proc_addr &&
                NULL != functions->get_physical_device_proc_addr((VkInstance)inst->instance, funcName)) {
                return true;
            }
        }
    }

    return false;
}

void loader_free_phys_dev_ext_table(struct loader_instance *inst) {
    for (uint32_t i = 0; i < MAX_NUM_UNKNOWN_EXTS; i++) {
        loader_instance_heap_free(inst, inst->phys_dev_ext_disp_functions[i]);
    }
    memset(inst->phys_dev_ext_disp_functions, 0, sizeof(inst->phys_dev_ext_disp_functions));
}

// This function returns a generic trampoline or terminator function
// address for any unknown physical device extension commands.  An array
// is used to keep a list of unknown entry points and their
// mapping to the physical device extension dispatch table (struct
// loader_phys_dev_ext_dispatch_table).
// For a given entry point string (funcName), if an existing mapping is
// found, then the address for that mapping is returned. The is_tramp
// parameter is used to decide whether to return a trampoline or terminator
// If it has not been seen before check if a layer or and ICD supports it.
// If so then a new entry in the function name array is added.
// Null is returned if discovered layer or ICD returns a non-NULL GetProcAddr for it
// or if the function name table is full.
void *loader_phys_dev_ext_gpa_impl(struct loader_instance *inst, const char *funcName, bool is_tramp) {
    assert(NULL != inst);

    // We should always check to see if any ICD supports it.
    if (!loader_check_icds_for_phys_dev_ext_address(inst, funcName)) {
        // If we're not checking layers, or we are and it's not in a layer, just
        // return
        if (!loader_check_layer_list_for_phys_dev_ext_address(inst, funcName)) {
            return NULL;
        }
    }

    // Linearly look through already added functions to make sure we haven't seen it before
    // if we have, return the function at the index found
    for (uint32_t i = 0; i < inst->phys_dev_ext_disp_function_count; i++) {
        if (inst->phys_dev_ext_disp_functions[i] && !strcmp(inst->phys_dev_ext_disp_functions[i], funcName)) {
            if (is_tramp) {
                return loader_get_phys_dev_ext_tramp(i);
            } else {
                return loader_get_phys_dev_ext_termin(i);
            }
        }
    }

    if (inst->phys_dev_ext_disp_function_count >= MAX_NUM_UNKNOWN_EXTS) {
        loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0, "loader_dev_ext_gpa: Exhausted the unknown physical device function array!");
        return NULL;
    }
    loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0,
               "loader_phys_dev_ext_gpa: Adding unknown physical function %s to internal store at index %u", funcName,
               inst->phys_dev_ext_disp_function_count);

    // add found function to phys_dev_ext_disp_functions;
    size_t funcName_len = strlen(funcName) + 1;
    inst->phys_dev_ext_disp_functions[inst->phys_dev_ext_disp_function_count] =
        (char *)loader_instance_heap_alloc(inst, funcName_len, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
    if (NULL == inst->phys_dev_ext_disp_functions[inst->phys_dev_ext_disp_function_count]) {
        // failed to allocate memory, return NULL
        return NULL;
    }
    strncpy(inst->phys_dev_ext_disp_functions[inst->phys_dev_ext_disp_function_count], funcName, funcName_len);

    uint32_t new_function_index = inst->phys_dev_ext_disp_function_count;
    // increment the count so that the subsequent logic includes the newly added entry point when searching for functions
    inst->phys_dev_ext_disp_function_count++;

    // Setup the ICD function pointers
    struct loader_icd_term *icd_term = inst->icd_terms;
    while (NULL != icd_term) {
        if (MIN_PHYS_DEV_EXTENSION_ICD_INTERFACE_VERSION <= icd_term->scanned_icd->interface_version &&
            NULL != icd_term->scanned_icd->GetPhysicalDeviceProcAddr) {
            icd_term->phys_dev_ext[new_function_index] =
                (PFN_PhysDevExt)icd_term->scanned_icd->GetPhysicalDeviceProcAddr(icd_term->instance, funcName);
            if (NULL != icd_term->phys_dev_ext[new_function_index]) {
                // Make sure we set the instance dispatch to point to the loader's terminator now since we can at least handle it in
                // one ICD.
                inst->disp->phys_dev_ext[new_function_index] = loader_get_phys_dev_ext_termin(new_function_index);

                loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "loader_phys_dev_ext_gpa: Driver %s returned ptr %p for %s",
                           icd_term->scanned_icd->lib_name, inst->disp->phys_dev_ext[new_function_index], funcName);
            }
        } else {
            icd_term->phys_dev_ext[new_function_index] = NULL;
        }

        icd_term = icd_term->next;
    }

    // Now, search for the first layer attached and query using it to get the first entry point.
    // Only set the instance dispatch table to it if it isn't NULL.
    for (uint32_t i = 0; i < inst->expanded_activated_layer_list.count; i++) {
        struct loader_layer_properties *layer_prop = &inst->expanded_activated_layer_list.list[i];
        if (layer_prop->interface_version > 1 && NULL != layer_prop->functions.get_physical_device_proc_addr) {
            void *layer_ret_function =
                (PFN_PhysDevExt)layer_prop->functions.get_physical_device_proc_addr(inst->instance, funcName);
            if (NULL != layer_ret_function) {
                inst->disp->phys_dev_ext[new_function_index] = layer_ret_function;
                loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "loader_phys_dev_ext_gpa: Layer %s returned ptr %p for %s",
                           layer_prop->info.layerName, inst->disp->phys_dev_ext[new_function_index], funcName);
                break;
            }
        }
    }

    if (is_tramp) {
        return loader_get_phys_dev_ext_tramp(new_function_index);
    } else {
        return loader_get_phys_dev_ext_termin(new_function_index);
    }
}
// Main interface functions, makes it clear whether it is getting a terminator or trampoline
void *loader_phys_dev_ext_gpa_tramp(struct loader_instance *inst, const char *funcName) {
    return loader_phys_dev_ext_gpa_impl(inst, funcName, true);
}
void *loader_phys_dev_ext_gpa_term(struct loader_instance *inst, const char *funcName) {
    return loader_phys_dev_ext_gpa_impl(inst, funcName, false);
}
// Returns the terminator if the function is supported in an ICD and if there is an entry for it in
// the function name array. Otherwise return NULL.
void *loader_phys_dev_ext_gpa_term_no_check(struct loader_instance *inst, const char *funcName) {
    assert(NULL != inst);

    // We should always check to see if any ICD supports it.
    if (!loader_check_icds_for_phys_dev_ext_address(inst, funcName)) {
        return NULL;
    }

    // Linearly look through already added functions to make sure we haven't seen it before
    // if we have, return the function at the index found
    for (uint32_t i = 0; i < inst->phys_dev_ext_disp_function_count; i++) {
        if (inst->phys_dev_ext_disp_functions[i] && !strcmp(inst->phys_dev_ext_disp_functions[i], funcName))
            return loader_get_phys_dev_ext_termin(i);
    }

    return NULL;
}