/*
 * Copyright 2021 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "modules/jetski/src/SurfaceThread.h"

#include "tools/window/DisplayParams.h"
#include "tools/window/WindowContext.h"
#include "tools/window/android/WindowContextFactory_android.h"

#include "include/core/SkCanvas.h"
#include "include/core/SkPicture.h"
#include "include/core/SkTypes.h"

SurfaceThread::SurfaceThread() {
    pipe(fPipe);
    fRunning = true;
    pthread_create(&fThread, nullptr, pthread_main, this);
}

void SurfaceThread::postMessage(const Message& message) const {
    write(fPipe[1], &message, sizeof(message));
}

void SurfaceThread::readMessage(Message* message) const {
    read(fPipe[0], message, sizeof(Message));
}

void SurfaceThread::release() {
    pthread_join(fThread, nullptr);
}

int SurfaceThread::message_callback(int /* fd */, int /* events */, void* data) {
    auto surfaceThread = (SurfaceThread*)data;
    Message message;
    surfaceThread->readMessage(&message);
    // get target surface from Message

    switch (message.fType) {
        case kInitialize: {
            skwindow::DisplayParams params;
            auto winctx = skwindow::MakeGLForAndroid(message.fNativeWindow, params);
            if (!winctx) {
                break;
            }
            *message.fWindowSurface = new WindowSurface(message.fNativeWindow, std::move(winctx));
            break;
        }
        case kDestroy: {
            SkDebugf("surface destroyed, shutting down thread");
            surfaceThread->fRunning = false;
            if(auto* windowSurface = reinterpret_cast<Surface*>(*message.fWindowSurface)){
                windowSurface->release(nullptr);
                delete windowSurface;
            }
            return 0;
        }
        case kRenderPicture: {
            sk_sp<SkPicture> picture(message.fPicture);
            if(auto* windowSurface = reinterpret_cast<Surface*>(*message.fWindowSurface)){
                windowSurface->getCanvas()->drawPicture(picture);
                windowSurface->flushAndSubmit();
            }
            break;
        }
        default: {
            // do nothing
        }
    }

    return 1;  // continue receiving callbacks
}

void* SurfaceThread::pthread_main(void* arg) {
    auto surfaceThread = (SurfaceThread*)arg;
    // Looper setup
    ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
    ALooper_addFd(looper, surfaceThread->fPipe[0], 1, ALOOPER_EVENT_INPUT,
               surfaceThread->message_callback, surfaceThread);

    while (surfaceThread->fRunning) {
        int ident = 0;
        while (ident == ALOOPER_POLL_CALLBACK) {
            ident = ALooper_pollOnce(0, nullptr, nullptr, nullptr);
        }

        if (ident >= 0) {
            SkDebugf("Unhandled ALooper_pollOnce ident=%d !", ident);
        }
    }
    return nullptr;
}
