/*
 * Copyright 2019 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 <apex/display.h>
#include <gui/SurfaceComposerClient.h>
#include <ui/DisplayMode.h>
#include <ui/DynamicDisplayInfo.h>
#include <ui/GraphicTypes.h>
#include <ui/PixelFormat.h>
#include <ui/StaticDisplayInfo.h>

#include <algorithm>
#include <optional>
#include <type_traits>
#include <vector>

namespace android::display::impl {

/**
 * Implementation of ADisplayConfig
 */
struct DisplayConfigImpl {
    /**
     * The ID of the display configuration.
     */
    size_t id;

    /**
     * The width in pixels of the display configuration.
     */
    int32_t width{0};

    /**
     * The height in pixels of the display configuration.
     */

    int32_t height{0};

    /**
     * The refresh rate of the display configuration, in frames per second.
     */
    float fps{0.0};

    /**
     * The vsync offset at which surfaceflinger runs, in nanoseconds.
     */
    int64_t sfOffset{0};

    /**
     * The vsync offset at which applications run, in nanoseconds.
     */
    int64_t appOffset{0};
};

// DisplayConfigImpl allocation is not managed through C++ memory apis, so
// preventing calling the destructor here.
static_assert(std::is_trivially_destructible<DisplayConfigImpl>::value);

/**
 * Implementation of ADisplay
 */
struct DisplayImpl {
    /**
     * A physical display ID, unique to this display.
     */
    PhysicalDisplayId id;

    /**
     * The type of the display, i.e. whether it is an internal or external
     * display.
     */
    ADisplayType type;

    /**
     * The preferred WCG dataspace
     */
    ADataSpace wcgDataspace;

    /**
     * The preferred WCG pixel format
     */
    AHardwareBuffer_Format wcgPixelFormat;

    /**
     * Number of supported configs
     */
    size_t numConfigs;

    /**
     * Set of supported configs by this display.
     */
    DisplayConfigImpl* configs;
};

// DisplayImpl allocation is not managed through C++ memory apis, so
// preventing calling the destructor here.
static_assert(std::is_trivially_destructible<DisplayImpl>::value);

} // namespace android::display::impl

using namespace android;
using namespace android::display::impl;

#define CHECK_NOT_NULL(name) \
    LOG_ALWAYS_FATAL_IF(name == nullptr, "nullptr passed as " #name " argument");

namespace android {

int ADisplay_acquirePhysicalDisplays(ADisplay*** outDisplays) {
    const std::vector<PhysicalDisplayId> ids = SurfaceComposerClient::getPhysicalDisplayIds();
    const size_t size = ids.size();
    if (size == 0) {
        return NO_INIT;
    }

    std::vector<DisplayConfigImpl> modesPerDisplay[size];
    ui::DisplayConnectionType displayConnectionTypes[size];
    int numModes = 0;
    for (int i = 0; i < size; ++i) {
        ui::StaticDisplayInfo staticInfo;
        if (const status_t status =
                    SurfaceComposerClient::getStaticDisplayInfo(ids[i].value, &staticInfo);
            status != OK) {
            return status;
        }
        displayConnectionTypes[i] = staticInfo.connectionType;

        ui::DynamicDisplayInfo dynamicInfo;
        if (const status_t status =
                    SurfaceComposerClient::getDynamicDisplayInfoFromId(ids[i].value, &dynamicInfo);
            status != OK) {
            return status;
        }
        const auto& modes = dynamicInfo.supportedDisplayModes;
        if (modes.empty()) {
            return NO_INIT;
        }

        numModes += modes.size();
        modesPerDisplay[i].reserve(modes.size());
        for (int j = 0; j < modes.size(); ++j) {
            const ui::DisplayMode& mode = modes[j];
            modesPerDisplay[i].emplace_back(
                    DisplayConfigImpl{static_cast<size_t>(mode.id), mode.resolution.getWidth(),
                                      mode.resolution.getHeight(), mode.peakRefreshRate,
                                      mode.sfVsyncOffset, mode.appVsyncOffset});
        }
    }

    ui::Dataspace defaultDataspace;
    ui::PixelFormat defaultPixelFormat;
    ui::Dataspace wcgDataspace;
    ui::PixelFormat wcgPixelFormat;

    const status_t status =
            SurfaceComposerClient::getCompositionPreference(&defaultDataspace, &defaultPixelFormat,
                                                            &wcgDataspace, &wcgPixelFormat);
    if (status != NO_ERROR) {
        return status;
    }

    // Here we allocate all our required memory in one block. The layout is as
    // follows:
    // ------------------------------------------------------------
    // | DisplayImpl pointers | DisplayImpls | DisplayConfigImpls |
    // ------------------------------------------------------------
    //
    // The caller will be given a DisplayImpl** which points to the beginning of
    // the block of DisplayImpl pointers.
    // Each DisplayImpl* points to a DisplayImpl in the second block.
    // Each DisplayImpl contains a DisplayConfigImpl*, which points to a
    // contiguous block of DisplayConfigImpls specific to that display.
    DisplayImpl** const impls = reinterpret_cast<DisplayImpl**>(
            malloc((sizeof(DisplayImpl) + sizeof(DisplayImpl*)) * size +
                   sizeof(DisplayConfigImpl) * numModes));
    DisplayImpl* const displayData = reinterpret_cast<DisplayImpl*>(impls + size);
    DisplayConfigImpl* configData = reinterpret_cast<DisplayConfigImpl*>(displayData + size);

    for (size_t i = 0; i < size; ++i) {
        const PhysicalDisplayId id = ids[i];
        const ADisplayType type = (displayConnectionTypes[i] == ui::DisplayConnectionType::Internal)
                ? ADisplayType::DISPLAY_TYPE_INTERNAL
                : ADisplayType::DISPLAY_TYPE_EXTERNAL;
        const std::vector<DisplayConfigImpl>& configs = modesPerDisplay[i];
        memcpy(configData, configs.data(), sizeof(DisplayConfigImpl) * configs.size());

        displayData[i] = DisplayImpl{id,
                                     type,
                                     static_cast<ADataSpace>(wcgDataspace),
                                     static_cast<AHardwareBuffer_Format>(wcgPixelFormat),
                                     configs.size(),
                                     configData};
        impls[i] = displayData + i;
        // Advance the configData pointer so that future configs are written to
        // the correct display.
        configData += configs.size();
    }

    *outDisplays = reinterpret_cast<ADisplay**>(impls);
    return size;
}

void ADisplay_release(ADisplay** displays) {
    if (displays == nullptr) {
        return;
    }
    free(displays);
}

float ADisplay_getMaxSupportedFps(ADisplay* display) {
    CHECK_NOT_NULL(display);
    DisplayImpl* impl = reinterpret_cast<DisplayImpl*>(display);
    float maxFps = 0.0;
    for (int i = 0; i < impl->numConfigs; ++i) {
        maxFps = std::max(maxFps, impl->configs[i].fps);
    }
    return maxFps;
}

ADisplayType ADisplay_getDisplayType(ADisplay* display) {
    CHECK_NOT_NULL(display);

    return reinterpret_cast<DisplayImpl*>(display)->type;
}

void ADisplay_getPreferredWideColorFormat(ADisplay* display, ADataSpace* outDataspace,
                                          AHardwareBuffer_Format* outPixelFormat) {
    CHECK_NOT_NULL(display);
    CHECK_NOT_NULL(outDataspace);
    CHECK_NOT_NULL(outPixelFormat);

    DisplayImpl* impl = reinterpret_cast<DisplayImpl*>(display);
    *outDataspace = impl->wcgDataspace;
    *outPixelFormat = impl->wcgPixelFormat;
}

int ADisplay_getCurrentConfig(ADisplay* display, ADisplayConfig** outConfig) {
    CHECK_NOT_NULL(display);

    ui::DynamicDisplayInfo info;
    DisplayImpl* impl = reinterpret_cast<DisplayImpl*>(display);

    if (const auto status =
                SurfaceComposerClient::getDynamicDisplayInfoFromId(impl->id.value, &info);
        status != OK) {
        return status;
    }

    for (size_t i = 0; i < impl->numConfigs; i++) {
        auto* config = impl->configs + i;
        if (config->id == info.activeDisplayModeId) {
            *outConfig = reinterpret_cast<ADisplayConfig*>(config);
            return OK;
        }
    }

    return NAME_NOT_FOUND;
}

int32_t ADisplayConfig_getWidth(ADisplayConfig* config) {
    CHECK_NOT_NULL(config);

    return reinterpret_cast<DisplayConfigImpl*>(config)->width;
}

int32_t ADisplayConfig_getHeight(ADisplayConfig* config) {
    CHECK_NOT_NULL(config);

    return reinterpret_cast<DisplayConfigImpl*>(config)->height;
}

float ADisplayConfig_getFps(ADisplayConfig* config) {
    CHECK_NOT_NULL(config);

    return reinterpret_cast<DisplayConfigImpl*>(config)->fps;
}

int64_t ADisplayConfig_getCompositorOffsetNanos(ADisplayConfig* config) {
    CHECK_NOT_NULL(config);

    return reinterpret_cast<DisplayConfigImpl*>(config)->sfOffset;
}

int64_t ADisplayConfig_getAppVsyncOffsetNanos(ADisplayConfig* config) {
    CHECK_NOT_NULL(config);

    return reinterpret_cast<DisplayConfigImpl*>(config)->appOffset;
}

} // namespace android
