/*
 * 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 "gles_gfx_api.h"
#include "gles_renderer.h"

#include "server_connection.h"
#include "server_listener.h"

#include <gapic/connection.h>
#include <gapic/log.h>
#include <gapic/supported_abis.h>

#include <string.h>

#include <memory>
#include <sstream>
#include <string>

namespace {

const uint32_t kProtocolVersion = 1;
const char kAuthTokenHeader[] = { 'A', 'U', 'T', 'H' };

}  // anonymous namespace

namespace gapir {

ServerListener::ServerListener(std::unique_ptr<gapic::Connection> conn, uint64_t maxMemorySize) :
        mConn(std::move(conn)),
        mMaxMemorySize(maxMemorySize) {
}

std::unique_ptr<ServerConnection> ServerListener::acceptConnection(int idleTimeoutMs, const char* authToken) {
    while (true) {
        GAPID_INFO("Waiting for new connection...");
        std::unique_ptr<gapic::Connection> client = mConn->accept(idleTimeoutMs);
        if (client == nullptr) {
            return nullptr;
        }

        if (authToken != nullptr) {
            GAPID_INFO("Checking auth-token...");
            char header[sizeof(kAuthTokenHeader)];
            if (client->recv(&header, sizeof(header)) != sizeof(header)) {
                GAPID_WARNING("Failed to read auth-token header");
                continue;
            }
            if (memcmp(header, kAuthTokenHeader, sizeof(kAuthTokenHeader)) != 0) {
                GAPID_WARNING("Invalid auth-token header");
                continue;
            }
            std::string gotAuthToken;
            if (!client->readString(&gotAuthToken) || gotAuthToken != authToken) {
                GAPID_WARNING("Invalid auth-token");
                continue;
            }
        }

        uint8_t connectionType;
        if (client->recv(&connectionType, sizeof(connectionType)) != sizeof(connectionType)) {
            GAPID_WARNING("Failed to read connection type");
            continue;
        }

        switch (connectionType) {
            case DEVICE_INFO: {
                GAPID_INFO("Sending device info");
                uint8_t ptrSize = sizeof(void*);
                uint8_t ptrAlign = std::alignment_of<void*>::value;
                uint8_t targetOs = TARGET_OS;
                // TODO(antiagainst): also return information about Vulkan implementation.
                std::unique_ptr<GlesRenderer> gl(GlesRenderer::create());
                gl->bind();

                Gles::GLint glUniformBufferAlignment = 1;
                gl->getApi<Gles>()->mFunctionStubs.glGetIntegerv(
                    Gles::GLenum::GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT,
                    &glUniformBufferAlignment
                );

                bool ok = client->send(kProtocolVersion);

                ok = ok && client->sendString(gapic::supportedABIs());

                bool glSupport = true;
                ok = ok && client->send(static_cast<uint8_t>(glSupport));
                if (glSupport) {
                    ok = ok && client->sendString(gl->extensions());
                    ok = ok && client->sendString(gl->name());
                    ok = ok && client->sendString(gl->vendor());
                    ok = ok && client->sendString(gl->version());
                    ok = ok && client->send(static_cast<uint16_t>(glUniformBufferAlignment));
                }

                gl->unbind();

                bool vkSupport = true; // TODO
                ok = ok && client->send(static_cast<uint8_t>(vkSupport));
                if (vkSupport) {
                    ok = ok && client->sendString("TODO: extensions");
                    ok = ok && client->sendString("TODO: name");
                    ok = ok && client->sendString("TODO: vendor");
                    ok = ok && client->sendString("TODO: version");
                }

                if (!ok) {
                    GAPID_WARNING("Failed to send device info");
                    break;
                }
                GAPID_INFO("Sent device info");
                break;
            }
            case REPLAY_REQUEST: {
                GAPID_INFO("Replay requested");
                std::unique_ptr<ServerConnection> conn = ServerConnection::create(std::move(client));
                if (conn != nullptr) {
                    return conn;
                } else {
                    GAPID_WARNING("Loading ServerConnection failed!");
                }
                break;
            }
            case SHUTDOWN_REQUEST: {
                GAPID_INFO("Shutdown request received!");
                return nullptr;
            }
            case PING: {
                client->sendString("PONG");
                break;
            }
            default: {
                GAPID_WARNING("Unknown connection type %d ignored", connectionType);
            }
        }
    }
}

}  // namespace gapir
