/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qopenwfddevice.h"

#include "qopenwfdport.h"
#include "qopenwfdscreen.h"

#include <QtCore/QDebug>

#include <WF/wfdext.h>
#include <gbm.h>

QOpenWFDDevice::QOpenWFDDevice(QOpenWFDIntegration *integration, WFDint device_enumeration)
    : mIntegration(integration)
    , mDeviceEnum(device_enumeration)
    , mCommitedDevice(false)
    , mWaitingForBindSourceEvent(false)
{
    mDevice = wfdCreateDevice(WFD_DEFAULT_DEVICE_ID,WFD_NONE);
    if (mDevice == WFD_INVALID_HANDLE)
        qDebug("failed to create device");

    mEvent = wfdCreateEvent(mDevice,0);
    if (mEvent == WFD_INVALID_HANDLE)
        qDebug("failed to create event handle");

    //initialize pipelines for device.
    wfdEnumeratePipelines(mDevice,WFD_NONE,0,WFD_NONE);

    initializeGbmAndEgl();

    WFDint numberOfPorts = wfdEnumeratePorts(mDevice,0,0,0);
    WFDint port_enumerations[numberOfPorts];
    WFDint actualNumberOfPorts = wfdEnumeratePorts(mDevice,port_enumerations,numberOfPorts,WFD_NONE);
    Q_ASSERT(actualNumberOfPorts == numberOfPorts);

    for (int i = 0; i < actualNumberOfPorts; i++)
    {
        QOpenWFDPort *port = new QOpenWFDPort(this,port_enumerations[i]);
        if (port->attached()) {
            mPorts.append(port);
        } else {
            delete port;
        }
    }

    int fd = wfdDeviceEventGetFD(mDevice,mEvent);
    mEventSocketNotifier = new QSocketNotifier(fd,QSocketNotifier::Read,this);
    connect(mEventSocketNotifier,SIGNAL(activated(QSocketDescriptor)),SLOT(readEvents()));

    mCommitedDevice = true;
    commit(WFD_COMMIT_ENTIRE_DEVICE, handle());
}

QOpenWFDDevice::~QOpenWFDDevice()
{
    delete mEventSocketNotifier;
    wfdDestroyEvent(mDevice,mEvent);

    for (int i = 0; i < mPorts.size(); i++) {
        //probably don't need to remove them from the list
        QList <WFDint> keys = mUsedPipelines.keys(mPorts.at(i));
        for (int keyIndex = 0; keyIndex < keys.size(); keyIndex++) {
            mUsedPipelines.remove(keys.at(keyIndex));
        }
        //but we have to delete them :)
        delete mPorts[i];
    }

    eglDestroyContext(mEglDisplay,mEglContext);
    eglTerminate(mEglDisplay);

    gbm_device_destroy(mGbmDevice);

    wfdDestroyDevice(mDevice);
}

WFDDevice QOpenWFDDevice::handle() const
{
    return mDevice;
}

QOpenWFDIntegration * QOpenWFDDevice::integration() const
{
    return mIntegration;
}

bool QOpenWFDDevice::isPipelineUsed(WFDint pipelineId)
{
    return mUsedPipelines.contains(pipelineId);
}

void QOpenWFDDevice::addToUsedPipelineSet(WFDint pipelineId,QOpenWFDPort *port)
{
    mUsedPipelines.insert(pipelineId,port);
}

void QOpenWFDDevice::removeFromUsedPipelineSet(WFDint pipelineId)
{
    mUsedPipelines.remove(pipelineId);
}

gbm_device * QOpenWFDDevice::gbmDevice() const

{
    return mGbmDevice;
}

EGLDisplay QOpenWFDDevice::eglDisplay() const
{
    return mEglDisplay;
}

EGLContext QOpenWFDDevice::eglContext() const
{
    return mEglContext;
}

void QOpenWFDDevice::commit(WFDCommitType type, WFDHandle handle)
{
    if (mCommitedDevice) {
        wfdDeviceCommit(mDevice,type,handle);
    }
}

void QOpenWFDDevice::waitForPipelineBindSourceCompleteEvent()
{
    mWaitingForBindSourceEvent = true;

    while (mWaitingForBindSourceEvent) {
        readEvents(WFD_FOREVER);
    }
}

void QOpenWFDDevice::readEvents(WFDtime wait)
{
    WFDEventType type = wfdDeviceEventWait(mDevice,mEvent,wait);

    if (type == WFD_EVENT_NONE || type == WFD_EVENT_DESTROYED) {
        return;
    }
    switch (type) {
    case WFD_EVENT_INVALID:
    case WFD_EVENT_NONE:
        return;
    case WFD_EVENT_DESTROYED:
        qDebug("Event or Device destoryed!");
        return;
    case WFD_EVENT_PORT_ATTACH_DETACH:
        handlePortAttachDetach();
        break;
    case WFD_EVENT_PORT_PROTECTION_FAILURE:
        qDebug("Port protection event handling not implemented");
        break;
    case WFD_EVENT_PIPELINE_BIND_SOURCE_COMPLETE:
        handlePipelineBindSourceComplete();
        break;
    case WFD_EVENT_PIPELINE_BIND_MASK_COMPLETE:
        qDebug("Pipeline bind mask event handling not implemented");
        break;
    default:
        qDebug("Unrecognized event type: %lu", static_cast<long unsigned int>(type));
        break;
    }


}

void QOpenWFDDevice::initializeGbmAndEgl()
{

    qDebug("initializing GBM and EGL");
    int fd = wfdGetDeviceAttribi(mDevice,WFD_DEVICE_ID);
    if (fd < 0) {
        qDebug("failed to get WFD_DEVICE_ID");
    }

    mGbmDevice = gbm_create_device(fd);

    setenv("EGL_PLATFORM", "drm",1);

    mEglDisplay = eglGetDisplay(mGbmDevice);

    EGLint minor, major;

    if (!eglInitialize(mEglDisplay,&major,&minor)) {
        qDebug("failed to initialize egl");
    }

    QByteArray eglExtensions = eglQueryString(mEglDisplay, EGL_EXTENSIONS);
    if (!eglExtensions.contains("EGL_KHR_surfaceless_opengl")) {
        qDebug("This egl implementation does not have the required EGL extension EGL_KHR_surfaceless_opengl");
    }

    eglBindAPI(EGL_OPENGL_ES_API);

    EGLint contextAttribs[] = {
        EGL_CONTEXT_CLIENT_VERSION, 2,
        EGL_NONE
    };

    mEglContext = eglCreateContext(mEglDisplay,NULL,EGL_NO_CONTEXT,contextAttribs);
    if (mEglContext == EGL_NO_CONTEXT) {
        qDebug("Failed to create EGL context");
    }

    eglCreateImage = (PFNEGLCREATEIMAGEKHRPROC) eglGetProcAddress("eglCreateImageKHR");
    if (!eglCreateImage) {
        qWarning("failed to load extension eglCreateImageKHR");
    }

    eglDestroyImage = (PFNEGLDESTROYIMAGEKHRPROC) eglGetProcAddress("eglDestroyImageKHR");
    if (!eglDestroyImage) {
        qWarning("failed to load extension eglDestoryImageKHR");
    }

    glEglImageTargetRenderBufferStorage = (PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) eglGetProcAddress("glEGLImageTargetRenderbufferStorageOES");
    if (!glEglImageTargetRenderBufferStorage) {
        qWarning("failed to load extension glEGLImageTargetRenderbufferStorageOES");
    }
}

void QOpenWFDDevice::handlePortAttachDetach()
{
    WFDint id = wfdGetEventAttribi(mDevice,mEvent,WFD_EVENT_PORT_ATTACH_PORT_ID);
    if (id == WFD_INVALID_PORT_ID)
        return;

    WFDint attachState = wfdGetEventAttribi(mDevice,mEvent,WFD_EVENT_PORT_ATTACH_STATE);
    if (attachState == WFD_TRUE) {
        int indexToAdd = -1;
        for (int i = 0; i < mPorts.size(); i++) {
            if (mPorts.at(i)->portId() == id) {
                indexToAdd = i;
                qDebug("found index to attach");
                break;
            }
        }
        if (indexToAdd >= 0) {
            mPorts[indexToAdd]->attach();
        } else {
            mPorts.append(new QOpenWFDPort(this,id));
        }

    } else {
        int indexToDelete = -1;
        for (int i = 0; i < mPorts.size(); i++) {
            if (mPorts.at(i)->portId() == id) {
                indexToDelete = i;
                break;
            }
        }
        if (indexToDelete >= 0) {
            QOpenWFDPort *portToDelete = mPorts.at(indexToDelete);
            mPorts.removeAt(indexToDelete);
            delete portToDelete;
        }
    }
}

void QOpenWFDDevice::handlePipelineBindSourceComplete()
{
    mWaitingForBindSourceEvent = false;

    WFDint overflow = wfdGetEventAttribi(mDevice,mEvent, WFD_EVENT_PIPELINE_BIND_QUEUE_OVERFLOW);
    if (overflow == WFD_TRUE) {
        qDebug("PIPELINE_BIND_QUEUE_OVERFLOW event occurred");
    }

    WFDint pipelineId = wfdGetEventAttribi(mDevice,mEvent,WFD_EVENT_PIPELINE_BIND_PIPELINE_ID);
    for (int i = 0; i < mPorts.size(); i++) {
        if (pipelineId != WFD_INVALID_PIPELINE_ID && mUsedPipelines.contains(pipelineId)) {
            QOpenWFDPort *port = mUsedPipelines.value(pipelineId);
            port->screen()->pipelineBindSourceComplete();
            break;
        }
    }
}
