// Copyright 2020 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 "host-common/AndroidPipe.h"

#include "aemu/base/synchronization/Lock.h"
#include "host-common/opengles.h"
#include <assert.h>
#include <atomic>
#include <memory>
#include <unordered_set>

#include <string.h>

using android::base::AutoLock;
using android::base::Lock;

namespace android {
namespace opengl {

struct ProcessPipeIdRegistry {
    Lock lock;
    std::unordered_set<uint64_t> ids;
};

static ProcessPipeIdRegistry sRegistry;

static bool sIdExistsInRegistry(uint64_t id) {
    AutoLock lock(sRegistry.lock);
    auto it = sRegistry.ids.find(id);
    return it != sRegistry.ids.end();
}

namespace {

// GLProcessPipe is a pipe service that is used for releasing graphics resources
// per guest process. At the time being, guest processes can acquire host color
// buffer handles / EGLImage handles and they need to be properly released when
// guest process exits unexpectedly. This class is used to detect if guest
// process exits, so that a proper cleanup function can be called.

// It is done by setting up a pipe per guest process before acquiring color
// buffer handles. When guest process exits, the pipe will be closed, and
// onGuestClose() will trigger the cleanup path.

class GLProcessPipe : public AndroidPipe {
public:
    //////////////////////////////////////////////////////////////////////////
    // The pipe service class for this implementation.
    class Service : public AndroidPipe::Service {
    public:
        Service() : AndroidPipe::Service("GLProcessPipe") {}

        bool canLoad() const override { return true; }

        AndroidPipe* create(void* hwPipe, const char* args, enum AndroidPipeFlags flags) override {
            return new GLProcessPipe(hwPipe, this, flags);
        }

        AndroidPipe* load(void* hwPipe, const char* args,
                         base::Stream* stream) override {
            return new GLProcessPipe(hwPipe, this, (AndroidPipeFlags)0, stream);
        }

        void preLoad(base::Stream* stream) override {
            GLProcessPipe::s_headId.store(stream->getBe64());
        }

        void preSave(base::Stream* stream) override {
            stream->putBe64(GLProcessPipe::s_headId.load());
        }
    };

    GLProcessPipe(void* hwPipe, Service* service, enum AndroidPipeFlags flags,
                  base::Stream* loadStream = nullptr)
        : AndroidPipe(hwPipe, service) {
        if (loadStream) {
            m_uniqueId = loadStream->getBe64();
            m_hasData = (loadStream->getByte() != 0);
        } else {
            if (flags & ANDROID_PIPE_VIRTIO_GPU_BIT) {
                m_uniqueId = (uint64_t)(uintptr_t)hwPipe;
                s_headId = m_uniqueId;
            } else {
                m_uniqueId = ++s_headId;
            }
        }
        AutoLock lock(sRegistry.lock);
        sRegistry.ids.insert(m_uniqueId);
        android_onGuestGraphicsProcessCreate(m_uniqueId);
    }

    ~GLProcessPipe() {
        AutoLock lock(sRegistry.lock);
        sRegistry.ids.erase(m_uniqueId);
    }

    void onSave(base::Stream* stream) override {
        stream->putBe64(m_uniqueId);
        stream->putByte(m_hasData ? 1 : 0);
    }

    void onGuestClose(PipeCloseReason reason) override {
        if (sIdExistsInRegistry(m_uniqueId)) {
            android_cleanupProcGLObjects(m_uniqueId);
        }
        delete this;
    }

    unsigned onGuestPoll() const override {
        return PIPE_POLL_IN | PIPE_POLL_OUT;
    }

    int onGuestRecv(AndroidPipeBuffer* buffers, int numBuffers) override {
        assert(buffers[0].size >= 8);
        if (m_hasData) {
            m_hasData = false;
            memcpy(buffers[0].data, (const char*)&m_uniqueId, sizeof(m_uniqueId));
            return sizeof(m_uniqueId);
        } else {
            return 0;
        }
    }

    int onGuestSend(const AndroidPipeBuffer* buffers,
                            int numBuffers,
                            void** newPipePtr) override {
        // The guest is supposed to send us a confirm code first. The code is
        // 100 (4 byte integer).
        assert(buffers[0].size >= 4);
        int32_t confirmInt = *((int32_t*)buffers[0].data);
        assert(confirmInt == 100);
        (void)confirmInt;
        m_hasData = true;
        return buffers[0].size;
    }

    void onGuestWantWakeOn(int flags) override {}

private:
    // An identifier for the guest process corresponding to this pipe.
    // With very high probability, all currently-active processes have unique
    // identifiers, since the IDs are assigned sequentially from a 64-bit ID
    // space.
    // Please change it if you ever have a use case that exhausts them
    uint64_t m_uniqueId;
    bool m_hasData = false;
    static std::atomic<uint64_t> s_headId;

};

std::atomic<uint64_t> GLProcessPipe::s_headId {0};

}

void registerGLProcessPipeService() {
    AndroidPipe::Service::add(std::make_unique<GLProcessPipe::Service>());
}

void forEachProcessPipeId(std::function<void(uint64_t)> f) {
    AutoLock lock(sRegistry.lock);
    for (auto id: sRegistry.ids) {
        f(id);
    }
}

void forEachProcessPipeIdRunAndErase(std::function<void(uint64_t)> f) {
    AutoLock lock(sRegistry.lock);
    auto it = sRegistry.ids.begin();
    while (it != sRegistry.ids.end()) {
        f(*it);
        it = sRegistry.ids.erase(it);
    }
}

}
}
