/*
* 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 "ProcessPipe.h"

#include <errno.h>
#include <log/log.h>
#include <pthread.h>
#include <qemu_pipe_bp.h>

#include "HostConnection.h"
#include "renderControl_enc.h"

#ifndef __Fuchsia__

#include "VirtioGpuPipeStream.h"
static VirtioGpuPipeStream* sVirtioGpuPipeStream = 0;
static int sStreamHandle = -1;

#endif // !__Fuchsia__

static QEMU_PIPE_HANDLE sProcPipe = 0;
// sProcUID is a unique ID per process assigned by the host.
// It is different from getpid().
static uint64_t           sProcUID = 0;
static HostConnectionType sConnType = HOST_CONNECTION_VIRTIO_GPU_PIPE;

static uint32_t* sSeqnoPtr = 0;

// Meant to be called only once per process.
static void initSeqno(void) {
    // So why do we reinitialize here? It's for testing purposes only;
    // we have a unit test that exercise the case where this sequence
    // number is reset as a result of guest process kill.
    if (sSeqnoPtr) delete sSeqnoPtr;
    sSeqnoPtr = new uint32_t;
    *sSeqnoPtr = 0;
}

#ifndef __Fuchsia__

static void sQemuPipeInit() {
    sProcPipe = qemu_pipe_open("GLProcessPipe");
    if (!qemu_pipe_valid(sProcPipe)) {
        sProcPipe = 0;
        ALOGW("Process pipe failed");
        return;
    }
    // Send a confirmation int to the host
    int32_t confirmInt = 100;
    if (qemu_pipe_write_fully(sProcPipe, &confirmInt, sizeof(confirmInt))) { // failed
        qemu_pipe_close(sProcPipe);
        sProcPipe = 0;
        ALOGW("Process pipe failed");
        return;
    }

    // Ask the host for per-process unique ID
    if (qemu_pipe_read_fully(sProcPipe, &sProcUID, sizeof(sProcUID))) {
        qemu_pipe_close(sProcPipe);
        sProcPipe = 0;
        sProcUID = 0;
        ALOGW("Process pipe failed");
        return;
    }
}

namespace {

static std::mutex sNeedInitMutex;
static bool sNeedInit = true;

}  // namespace

static void processPipeDoInit(uint32_t noRenderControlEnc) {
    initSeqno();

    // No need to setup auxiliary pipe stream in this case
    if (noRenderControlEnc) return;

    switch (sConnType) {
        // TODO: Move those over too
        case HOST_CONNECTION_QEMU_PIPE:
        case HOST_CONNECTION_ADDRESS_SPACE:
            sQemuPipeInit();
            break;
        case HOST_CONNECTION_VIRTIO_GPU_PIPE:
        case HOST_CONNECTION_VIRTIO_GPU_ADDRESS_SPACE: {
            sVirtioGpuPipeStream = new VirtioGpuPipeStream(4096, sStreamHandle);
            sProcUID = sVirtioGpuPipeStream->initProcessPipe();
            break;
        }
    }
}
#endif // !__Fuchsia__

bool processPipeInit(int streamHandle, HostConnectionType connType, uint32_t noRenderControlEnc) {
    sConnType = connType;
#ifndef __Fuchsia__
    sStreamHandle = streamHandle;
#endif // !__Fuchsia

    {
        std::lock_guard<std::mutex> lock(sNeedInitMutex);

        if (sNeedInit) {
            sNeedInit = false;
            processPipeDoInit(noRenderControlEnc);

            if (noRenderControlEnc) {
                return true;
            }

#ifndef __Fuchsia__
            if (!sProcPipe && !sVirtioGpuPipeStream) {
                return false;
            }
#endif
        }
    }

    return true;
}

uint64_t getPuid() {
    return sProcUID;
}

void processPipeRestart() {
    std::lock_guard<std::mutex> lock(sNeedInitMutex);

    ALOGW("%s: restarting process pipe\n", __func__);
    bool isPipe = false;

    switch (sConnType) {
        // TODO: Move those over too
        case HOST_CONNECTION_QEMU_PIPE:
        case HOST_CONNECTION_ADDRESS_SPACE:
            isPipe = true;
            break;
        case HOST_CONNECTION_VIRTIO_GPU_PIPE:
        case HOST_CONNECTION_VIRTIO_GPU_ADDRESS_SPACE: {
            isPipe = false;
            break;
        }
    }

    sProcUID = 0;

    if (isPipe) {
        if (qemu_pipe_valid(sProcPipe)) {
            qemu_pipe_close(sProcPipe);
            sProcPipe = 0;
        }
    } else {
        if (sVirtioGpuPipeStream) {
            delete sVirtioGpuPipeStream;
            sVirtioGpuPipeStream = nullptr;
        }
    }

    if (sConnType == HOST_CONNECTION_VIRTIO_GPU_PIPE ||
        sConnType == HOST_CONNECTION_VIRTIO_GPU_ADDRESS_SPACE) {
        VirtGpuDevice::resetInstance();
    }

    sNeedInit = true;
}

void refreshHostConnection() {
    HostConnection* hostConn = HostConnection::get();
    ExtendedRCEncoderContext* rcEnc = hostConn->rcEncoder();
    rcEnc->rcSetPuid(rcEnc, sProcUID);
}

uint32_t* getSeqnoPtrForProcess() {
    // It's assumed process pipe state has already been initialized.
    return sSeqnoPtr;
}
