/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * 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 <cutils/log.h>

#include <inttypes.h>
#include <cstdlib>
#include <new>
#include <array>

#include "hwc2.h"

static int hwc2_device_open(const struct hw_module_t *module, const char *name,
    struct hw_device_t **device);

static int32_t hwc2_device_close(struct hw_device_t *device);

static struct hw_module_methods_t hwc2_module_methods = {
    .open = hwc2_device_open
};

hw_module_t HAL_MODULE_INFO_SYM = {
    .tag = HARDWARE_MODULE_TAG,
    .id = HWC_HARDWARE_MODULE_ID,
    .name = "NVIDIA Tegra hwcomposer module",
    .author = "AOSP",
    .methods = &hwc2_module_methods,
};


hwc2_error_t create_virtual_display(hwc2_device_t* /*device*/,
        uint32_t /*width*/, uint32_t /*height*/,
        android_pixel_format_t* /*format*/,
        hwc2_display_t* /*out_display*/)
{
    return HWC2_ERROR_NONE;
}

hwc2_error_t destroy_virtual_display(hwc2_device_t* /*device*/,
        hwc2_display_t /*display*/)
{
    return HWC2_ERROR_NONE;
}

void dump(hwc2_device_t* /*device*/, uint32_t* /*out_size*/,
        char* /*out_buffer*/)
{
    return;
}

uint32_t get_max_virtual_display_count(hwc2_device_t* /*device*/)
{
    return HWC2_ERROR_NONE;
}

hwc2_error_t register_callback(hwc2_device_t *device,
        hwc2_callback_descriptor_t descriptor,
        hwc2_callback_data_t callback_data, hwc2_function_pointer_t pointer)
{
    hwc2_dev *dev = reinterpret_cast<hwc2_context *>(device)->hwc2_dev;
    return dev->register_callback(descriptor, callback_data, pointer);
}

hwc2_error_t accept_display_changes(hwc2_device_t* /*device*/,
        hwc2_display_t /*display*/)
{
    return HWC2_ERROR_NONE;
}

hwc2_error_t create_layer(hwc2_device_t *device, hwc2_display_t display,
        hwc2_layer_t *out_layer)
{
    hwc2_dev *dev = reinterpret_cast<hwc2_context *>(device)->hwc2_dev;
    return dev->create_layer(display, out_layer);
}

hwc2_error_t destroy_layer(hwc2_device_t *device, hwc2_display_t display,
        hwc2_layer_t layer)
{
    hwc2_dev *dev = reinterpret_cast<hwc2_context *>(device)->hwc2_dev;
    return dev->destroy_layer(display, layer);
}

hwc2_error_t get_active_config(hwc2_device_t *device, hwc2_display_t display,
        hwc2_config_t *out_config)
{
    hwc2_dev *dev = reinterpret_cast<hwc2_context *>(device)->hwc2_dev;
    return dev->get_active_config(display, out_config);
}

hwc2_error_t get_changed_composition_types(hwc2_device_t* /*device*/,
        hwc2_display_t /*display*/, uint32_t* /*out_num_elements*/,
        hwc2_layer_t* /*out_layers*/, hwc2_composition_t* /*out_types*/)
{
    return HWC2_ERROR_NONE;
}

hwc2_error_t get_client_target_support(hwc2_device_t* /*device*/,
        hwc2_display_t /*display*/, uint32_t /*width*/, uint32_t /*height*/,
        android_pixel_format_t /*format*/, android_dataspace_t /*dataspace*/)
{
    return HWC2_ERROR_NONE;
}

hwc2_error_t get_color_modes(hwc2_device_t* /*device*/,
        hwc2_display_t /*display*/, uint32_t* /*out_num_modes*/,
        android_color_mode_t* /*out_modes*/)
{
    return HWC2_ERROR_NONE;
}

hwc2_error_t get_display_attribute(hwc2_device_t *device,
        hwc2_display_t display, hwc2_config_t config,
        hwc2_attribute_t attribute, int32_t *out_value)
{
    hwc2_dev *dev = reinterpret_cast<hwc2_context *>(device)->hwc2_dev;
    return dev->get_display_attribute(display, config, attribute, out_value);
}

hwc2_error_t get_display_configs(hwc2_device_t *device, hwc2_display_t display,
        uint32_t *out_num_configs, hwc2_config_t *out_configs)
{
    hwc2_dev *dev = reinterpret_cast<hwc2_context *>(device)->hwc2_dev;
    return dev->get_display_configs(display, out_num_configs, out_configs);
}

hwc2_error_t get_display_name(hwc2_device_t *device, hwc2_display_t display,
        uint32_t *out_size, char *out_name)
{
    hwc2_dev *dev = reinterpret_cast<hwc2_context *>(device)->hwc2_dev;
    return dev->get_display_name(display, out_size, out_name);
}

hwc2_error_t get_display_requests(hwc2_device_t* /*device*/,
        hwc2_display_t /*display*/,
        hwc2_display_request_t* /*out_display_requests*/,
        uint32_t* /*out_num_elements*/, hwc2_layer_t* /*out_layers*/,
        hwc2_layer_request_t* /*out_layer_requests*/)
{
    return HWC2_ERROR_NONE;
}

hwc2_error_t get_display_type(hwc2_device_t *device, hwc2_display_t display,
        hwc2_display_type_t *out_type)
{
    hwc2_dev *dev = reinterpret_cast<hwc2_context *>(device)->hwc2_dev;
    return dev->get_display_type(display, out_type);
}

hwc2_error_t get_doze_support(hwc2_device_t *device, hwc2_display_t display,
        int32_t *out_support)
{
    hwc2_dev *dev = reinterpret_cast<hwc2_context *>(device)->hwc2_dev;
    return dev->get_doze_support(display, out_support);
}

hwc2_error_t get_hdr_capabilities(hwc2_device_t* /*device*/,
        hwc2_display_t /*display*/, uint32_t* /*out_num_types*/,
        android_hdr_t* /*out_types*/, float* /*out_max_luminance*/,
        float* /*out_max_average_luminance*/, float* /*out_min_luminance*/)
{
    return HWC2_ERROR_NONE;
}

hwc2_error_t get_release_fences(hwc2_device_t* /*device*/,
        hwc2_display_t /*display*/, uint32_t* /*out_num_elements*/,
        hwc2_layer_t* /*out_layers*/, int32_t* /*out_fences*/)
{
    return HWC2_ERROR_NONE;
}

hwc2_error_t present_display(hwc2_device_t* /*device*/,
        hwc2_display_t /*display*/, int32_t* /*out_present_fence*/)
{
    return HWC2_ERROR_NONE;
}

hwc2_error_t set_active_config(hwc2_device_t *device, hwc2_display_t display,
        hwc2_config_t config)
{
    hwc2_dev *dev = reinterpret_cast<hwc2_context *>(device)->hwc2_dev;
    return dev->set_active_config(display, config);
}

hwc2_error_t set_client_target(hwc2_device_t* /*device*/,
        hwc2_display_t /*display*/, buffer_handle_t /*target*/,
        int32_t /*acquire_fence*/, android_dataspace_t /*dataspace*/,
        hwc_region_t /*damage*/)
{
    return HWC2_ERROR_NONE;
}

hwc2_error_t set_color_mode(hwc2_device_t* /*device*/,
        hwc2_display_t /*display*/, android_color_mode_t /*mode*/)
{
    return HWC2_ERROR_NONE;
}

hwc2_error_t set_color_transform(hwc2_device_t* /*device*/,
        hwc2_display_t /*display*/, const float* /*matrix*/,
        android_color_transform_t /*hint*/)
{
    return HWC2_ERROR_NONE;
}

hwc2_error_t set_output_buffer(hwc2_device_t* /*device*/,
        hwc2_display_t /*display*/, buffer_handle_t /*buffer*/,
        int32_t /*release_fence*/)
{
    return HWC2_ERROR_NONE;
}

hwc2_error_t set_power_mode(hwc2_device_t *device, hwc2_display_t display,
        hwc2_power_mode_t mode)
{
    hwc2_dev *dev = reinterpret_cast<hwc2_context *>(device)->hwc2_dev;
    return dev->set_power_mode(display, mode);
}

hwc2_error_t set_vsync_enabled(hwc2_device_t *device, hwc2_display_t display,
        hwc2_vsync_t enabled)
{
    hwc2_dev *dev = reinterpret_cast<hwc2_context *>(device)->hwc2_dev;
    return dev->set_vsync_enabled(display, static_cast<hwc2_vsync_t>(enabled));
}

hwc2_error_t validate_display(hwc2_device_t* /*device*/,
        hwc2_display_t /*display*/, uint32_t* /*out_num_types*/,
        uint32_t* /*out_num_requests*/)
{
    return HWC2_ERROR_NONE;
}

hwc2_error_t set_cursor_position(hwc2_device_t *device, hwc2_display_t display,
        hwc2_layer_t layer, int32_t x, int32_t y)
{
    hwc2_dev *dev = reinterpret_cast<hwc2_context *>(device)->hwc2_dev;
    return dev->set_cursor_position(display, layer, x, y);
}

hwc2_error_t set_layer_buffer(hwc2_device_t *device, hwc2_display_t display,
        hwc2_layer_t layer, buffer_handle_t buffer, int32_t acquire_fence)
{
    hwc2_dev *dev = reinterpret_cast<hwc2_context *>(device)->hwc2_dev;
    return dev->set_layer_buffer(display, layer, buffer, acquire_fence);
}

hwc2_error_t set_layer_surface_damage(hwc2_device_t *device,
        hwc2_display_t display, hwc2_layer_t layer, hwc_region_t damage)
{
    hwc2_dev *dev = reinterpret_cast<hwc2_context *>(device)->hwc2_dev;
    return dev->set_layer_surface_damage(display, layer, damage);
}

hwc2_error_t set_layer_blend_mode(hwc2_device_t *device, hwc2_display_t display,
        hwc2_layer_t layer, hwc2_blend_mode_t mode)
{
    hwc2_dev *dev = reinterpret_cast<hwc2_context *>(device)->hwc2_dev;
    return dev->set_layer_blend_mode(display, layer, mode);
}

hwc2_error_t set_layer_color(hwc2_device_t *device,
        hwc2_display_t display, hwc2_layer_t layer,
        hwc_color_t color)
{
    hwc2_dev *dev = reinterpret_cast<hwc2_context *>(device)->hwc2_dev;
    return dev->set_layer_color(display, layer, color);
}

hwc2_error_t set_layer_composition_type(hwc2_device_t *device,
        hwc2_display_t display, hwc2_layer_t layer, hwc2_composition_t type)
{
    hwc2_dev *dev = reinterpret_cast<hwc2_context *>(device)->hwc2_dev;
    return dev->set_layer_composition_type(display, layer, type);
}

hwc2_error_t set_layer_dataspace(hwc2_device_t *device, hwc2_display_t display,
        hwc2_layer_t layer, android_dataspace_t dataspace)
{
    hwc2_dev *dev = reinterpret_cast<hwc2_context *>(device)->hwc2_dev;
    return dev->set_layer_dataspace(display, layer, dataspace);
}

hwc2_error_t set_layer_display_frame(hwc2_device_t *device,
        hwc2_display_t display, hwc2_layer_t layer, hwc_rect_t frame)
{
    hwc2_dev *dev = reinterpret_cast<hwc2_context *>(device)->hwc2_dev;
    return dev->set_layer_display_frame(display, layer, frame);
}

hwc2_error_t set_layer_plane_alpha(hwc2_device_t *device,
        hwc2_display_t display, hwc2_layer_t layer, float alpha)
{
    hwc2_dev *dev = reinterpret_cast<hwc2_context *>(device)->hwc2_dev;
    return dev->set_layer_plane_alpha(display, layer, alpha);
}

hwc2_error_t set_layer_source_crop(hwc2_device_t *device,
        hwc2_display_t display, hwc2_layer_t layer, hwc_frect_t crop)
{
    hwc2_dev *dev = reinterpret_cast<hwc2_context *>(device)->hwc2_dev;
    return dev->set_layer_source_crop(display, layer, crop);
}

hwc2_error_t set_layer_transform(hwc2_device_t *device, hwc2_display_t display,
        hwc2_layer_t layer, hwc_transform_t transform)
{
    hwc2_dev *dev = reinterpret_cast<hwc2_context *>(device)->hwc2_dev;
    return dev->set_layer_transform(display, layer, transform);
}

hwc2_error_t set_layer_visible_region(hwc2_device_t *device,
        hwc2_display_t display, hwc2_layer_t layer, hwc_region_t visible)
{
    hwc2_dev *dev = reinterpret_cast<hwc2_context *>(device)->hwc2_dev;
    return dev->set_layer_visible_region(display, layer, visible);
}

hwc2_error_t set_layer_z_order(hwc2_device_t *device, hwc2_display_t display,
        hwc2_layer_t layer, uint32_t z)
{
    hwc2_dev *dev = reinterpret_cast<hwc2_context *>(device)->hwc2_dev;
    return dev->set_layer_z_order(display, layer, z);
}

/* Indexed using the hwc2_function_descriptor_t enum to find the corresponding
 * function */
static const std::array<hwc2_function_pointer_t, 44> hwc2_func_ptrs = {{
    /* Index 0 corresponds to HWC2_FUNCTION_INVALID */
    (hwc2_function_pointer_t) nullptr,
    (hwc2_function_pointer_t) accept_display_changes,
    (hwc2_function_pointer_t) create_layer,
    (hwc2_function_pointer_t) create_virtual_display,
    (hwc2_function_pointer_t) destroy_layer,
    (hwc2_function_pointer_t) destroy_virtual_display,
    (hwc2_function_pointer_t) dump,
    (hwc2_function_pointer_t) get_active_config,
    (hwc2_function_pointer_t) get_changed_composition_types,
    (hwc2_function_pointer_t) get_client_target_support,
    (hwc2_function_pointer_t) get_color_modes,
    (hwc2_function_pointer_t) get_display_attribute,
    (hwc2_function_pointer_t) get_display_configs,
    (hwc2_function_pointer_t) get_display_name,
    (hwc2_function_pointer_t) get_display_requests,
    (hwc2_function_pointer_t) get_display_type,
    (hwc2_function_pointer_t) get_doze_support,
    (hwc2_function_pointer_t) get_hdr_capabilities,
    (hwc2_function_pointer_t) get_max_virtual_display_count,
    (hwc2_function_pointer_t) get_release_fences,
    (hwc2_function_pointer_t) present_display,
    (hwc2_function_pointer_t) register_callback,
    (hwc2_function_pointer_t) set_active_config,
    (hwc2_function_pointer_t) set_client_target,
    (hwc2_function_pointer_t) set_color_mode,
    (hwc2_function_pointer_t) set_color_transform,
    (hwc2_function_pointer_t) set_cursor_position,
    (hwc2_function_pointer_t) set_layer_blend_mode,
    (hwc2_function_pointer_t) set_layer_buffer,
    (hwc2_function_pointer_t) set_layer_color,
    (hwc2_function_pointer_t) set_layer_composition_type,
    (hwc2_function_pointer_t) set_layer_dataspace,
    (hwc2_function_pointer_t) set_layer_display_frame,
    (hwc2_function_pointer_t) set_layer_plane_alpha,
    (hwc2_function_pointer_t) nullptr, /*set_layer_sideband_stream unsupported*/
    (hwc2_function_pointer_t) set_layer_source_crop,
    (hwc2_function_pointer_t) set_layer_surface_damage,
    (hwc2_function_pointer_t) set_layer_transform,
    (hwc2_function_pointer_t) set_layer_visible_region,
    (hwc2_function_pointer_t) set_layer_z_order,
    (hwc2_function_pointer_t) set_output_buffer,
    (hwc2_function_pointer_t) set_power_mode,
    (hwc2_function_pointer_t) set_vsync_enabled,
    (hwc2_function_pointer_t) validate_display,
}};

hwc2_function_pointer_t get_function(struct hwc2_device* /*device*/,
        /*hwc2_function_descriptor_t*/ int32_t descriptor)
{
    if (descriptor == HWC2_FUNCTION_INVALID ||
            static_cast<size_t>(descriptor) >= hwc2_func_ptrs.size()) {
        ALOGW("invalid descriptor");
        return nullptr;
    }
    return hwc2_func_ptrs[descriptor];
}

void get_capabilities(struct hwc2_device* /*device*/, uint32_t *out_count,
        /*hwc2_capability_t*/ int32_t* /*outCapabilities*/)
{
    *out_count = 0;
}

static int32_t hwc2_device_close(struct hw_device_t *device)
{
    hwc2_context *ctx = reinterpret_cast<hwc2_context *>(device);
    delete ctx->hwc2_dev;
    delete ctx;
    return 0;
}

static int hwc2_device_open(const struct hw_module_t *module, const char *name,
        struct hw_device_t **hw_device)
{
    if (strcmp(name, HWC_HARDWARE_COMPOSER))
        return -EINVAL;

    hwc2_context *ctx = new hwc2_context();
    if (!ctx) {
        ALOGE("failed to allocate hwc2_context");
        return -ENOMEM;
    }

    ctx->hwc2_device.common.tag = HARDWARE_DEVICE_TAG;
    ctx->hwc2_device.common.version = HWC_DEVICE_API_VERSION_2_0;
    ctx->hwc2_device.common.module = const_cast<hw_module_t *>(module);
    ctx->hwc2_device.common.close = hwc2_device_close;
    ctx->hwc2_device.getFunction = get_function;
    ctx->hwc2_device.getCapabilities = get_capabilities;

    ctx->hwc2_dev = new hwc2_dev();
    if (!ctx->hwc2_dev) {
        ALOGE("failed to allocate hwc2_dev");
        delete ctx;
        return -ENOMEM;
    }

    int ret = ctx->hwc2_dev->open_adf_device();
    if (ret < 0) {
        ALOGE("failed to open adf device: %s", strerror(ret));
        delete ctx->hwc2_dev;
        delete ctx;
        return ret;
    }

    *hw_device = &ctx->hwc2_device.common;

    return 0;
}
