/*
 * Copyright (C) 2020 Uniontech Technology Co., Ltd.
 *
 * Author:     xinbo wang <wangxinbo@uniontech.com>
 *
 * Maintainer: xinbo wang <wangxinbo@uniontech.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <iostream>
#include <unistd.h>

#include "QLibrary"

#include <wmjack/dtk_wmjack.h>
#include "dnd_security.h"

typedef int32_t (*GetWindowPidPtr)(int32_t /*window_id*/);
typedef void (*InitDtkDisplayPtr)();

void testResolve()
{
    std::cout << "testResolve:start" << std::endl;
    QLibrary lib("dtkwmjack", 1);
    std::cout << lib.load() << std::endl;

    auto func = (GetWindowPidPtr)lib.resolve("GetWindowPID");
    auto init = (InitDtkDisplayPtr)lib.resolve("InitDtkWmDisplay");

    init();
    if (func == nullptr) {
        std::cout << "testResolve:can not resolve func" << std::endl;
    } else {
        std::cout << "testResolve:" << func(0x4e00007) << std::endl;
    }
    std::cout << "testResolve:done" << std::endl;
}

void testNormal()
{
    std::cout << "testNormal:start" << std::endl;
    InitDtkWmDisplay();

    auto windows = GetAllWindowStates();
    auto data = (WindowState *)windows->data;

    if (windows && windows->size > 0) {
        void *p;
        dtk_array_for_each(p, windows, sizeof(WindowState))
        {
            auto p1 = (WindowState *)(p);
            std::cout << "testNormal:windowId=" << p1->windowId << std::endl;
        }
    }

    std::cout << "testNormal:done" << std::endl;
}

void example()
{
    InitDtkDisplay();
    InitDtkWmDisplay();

    int window_id = -1;
    int session_id = GetSecuritySession(SecClipboardCopy);

    dtk_array *arrays = GetAllWindowStates();
    if (arrays && arrays->size > 0) {
        void *p1;
        dtk_array_for_each(p1, arrays, sizeof(WindowState))
        {
            auto p = (WindowState *)(p1);
            std::cout << "example:pid:= " << p->pid << " windowid= " << p->windowId << " resourceName= " << p->resourceName
                      << std::endl;
            if (window_id == -1) {
                window_id = p->windowId;
                break;
            }
        }
    }

    if (window_id != 0) {
        // get window info
        std::cout << "example:pid:" << GetWindowPID(window_id) << std::endl;
        WindowState *state = GetWindowState(window_id);
        if (state) {
            std::cout << "example:name:" << state->resourceName << std::endl;
        } else {
            std::cout << "example:failed to get window state for window:" << window_id << std::endl;
        }
    }

    dtk_array *pids = GetSecurityClients();
    if (pids && pids->size > 0) {
        void *p;
        dtk_array_for_each(p, pids, sizeof(uint32_t))
        {
            auto p1 = (uint32_t *)(p);
            std::cout << "example:=======pid======== " << (*p1) << std::endl;
        }

        dtk_array_release(pids);
    }

    DestroySecuritySession(session_id);

    while (true) {
        sleep(10);
    }
    DestoryDtkDisplay();
}

int main()
{
    //putenv("XDG_SESSION_TYPE=wayland");
    putenv("XDG_SESSION_TYPE=x11");
    // testNormal();
    // testResolve();
     example();
}
