/**************************************************************************
 *
 * Copyright 2015 Alexander Trukhin
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 **************************************************************************/

#include <iostream>

#include "metric_writer.hpp"

void ProfilerQuery::writeMetricHeaderCallback(Metric* metric, int event, void* data, int error,
                                      void* userData) {
    std::cout << "\t" << metric->name();
}

void ProfilerQuery::writeMetricEntryCallback(Metric* metric, int event, void* data, int error,
                                     void* userData) {
    if (error) {
        std::cout << "\t" << "#ERR" << error;
        return;
    }
    if (!data) {
        std::cout << "\t" << "-";
        return;
    }
    switch(metric->numType()) {
        case CNT_NUM_UINT: std::cout << "\t" << *(reinterpret_cast<unsigned*>(data)); break;
        case CNT_NUM_FLOAT: std::cout << "\t" << *(reinterpret_cast<float*>(data)); break;
        case CNT_NUM_DOUBLE: std::cout << "\t" << *(reinterpret_cast<double*>(data)); break;
        case CNT_NUM_BOOL: std::cout << "\t" << *(reinterpret_cast<bool*>(data)); break;
        case CNT_NUM_UINT64: std::cout << "\t" << *(reinterpret_cast<uint64_t*>(data)); break;
        case CNT_NUM_INT64: std::cout << "\t" << *(reinterpret_cast<int64_t*>(data)); break;
    }
}

void ProfilerQuery::writeMetricHeader(QueryBoundary qb) const {
    for (auto &a : *metricBackends) {
        a->enumDataQueryId(eventId, &writeMetricHeaderCallback, qb);
    }
    std::cout << std::endl;
}

void ProfilerQuery::writeMetricEntry(QueryBoundary qb) const {
    for (auto &a : *metricBackends) {
        a->enumDataQueryId(eventId, &writeMetricEntryCallback, qb);
    }
    std::cout << std::endl;
}

template<typename T>
T ProfilerCall::StringTable<T>::getId(const std::string &str) {
    auto res = stringLookupTable.find(str);
    T index;
    if (res == stringLookupTable.end()) {
        index = static_cast<T>(strings.size());
        strings.push_back(str);
        stringLookupTable[str] = index;
    } else {
        index = res->second;
    }
    return index;
}

template<typename T>
std::string ProfilerCall::StringTable<T>::getString(T id) {
    return strings[static_cast<typename decltype(stringLookupTable)::size_type>(id)];
}


ProfilerCall::ProfilerCall(unsigned eventId, const data* queryData)
    : ProfilerQuery(QUERY_BOUNDARY_CALL, eventId)
{
    if (queryData) {
        isFrameEnd = queryData->isFrameEnd;
        no = queryData->no;
        program = queryData->program;
        nameTableEntry = nameTable.getId(queryData->name);
    }
}


void ProfilerCall::writeHeader() const {
    std::cout << "#\tcall no\tprogram\tname";
    ProfilerQuery::writeMetricHeader(QUERY_BOUNDARY_CALL);
}

void ProfilerCall::writeEntry() const {
    if (isFrameEnd) {
        std::cout << "frame_end" << std::endl;
    } else {
        std::cout << "call"
            << "\t" << no
            << "\t" << program
            << "\t" << nameTable.getString(nameTableEntry);
        ProfilerQuery::writeMetricEntry(QUERY_BOUNDARY_CALL);
    }
}


void ProfilerDrawcall::writeHeader() const {
    std::cout << "#\tcall no\tprogram\tname";
    ProfilerQuery::writeMetricHeader(QUERY_BOUNDARY_DRAWCALL);
}

void ProfilerDrawcall::writeEntry() const {
    if (isFrameEnd) {
        std::cout << "frame_end" << std::endl;
    } else {
        std::cout << "call"
            << "\t" << no
            << "\t" << program
            << "\t" << nameTable.getString(nameTableEntry);
        ProfilerQuery::writeMetricEntry(QUERY_BOUNDARY_DRAWCALL);
    }
}


void ProfilerFrame::writeHeader() const {
    std::cout << "#";
    ProfilerQuery::writeMetricHeader(QUERY_BOUNDARY_FRAME);
}

void ProfilerFrame::writeEntry() const {
    std::cout << "frame";
    ProfilerQuery::writeMetricEntry(QUERY_BOUNDARY_FRAME);
}


MetricWriter::MetricWriter(std::vector<MetricBackend*> &metricBackends,
                           const MmapAllocator<char> &alloc)
    : frameQueue(MmapAllocator<ProfilerCall>(alloc)),
      callQueue(MmapAllocator<ProfilerCall>(alloc)),
      drawcallQueue(MmapAllocator<ProfilerCall>(alloc))
{
    ProfilerQuery::metricBackends = &metricBackends;
}

void MetricWriter::addQuery(QueryBoundary boundary, unsigned eventId,
                            const void* queryData)
{
    switch (boundary) {
        case QUERY_BOUNDARY_FRAME:
            frameQueue.emplace_back(eventId);
            break;
        case QUERY_BOUNDARY_CALL:
            callQueue.emplace_back(eventId,
                    reinterpret_cast<const ProfilerCall::data*>(queryData));
            break;
        case QUERY_BOUNDARY_DRAWCALL:
            drawcallQueue.emplace_back(eventId,
                    reinterpret_cast<const ProfilerCall::data*>(queryData));
            break;
        default:
            break;
    }
}

void MetricWriter::writeQuery(QueryBoundary boundary) {
    switch (boundary) {
        case QUERY_BOUNDARY_FRAME:
            frameQueue.front().writeEntry();
            frameQueue.pop_front();
            break;
        case QUERY_BOUNDARY_CALL:
            callQueue.front().writeEntry();
            callQueue.pop_front();
            break;
        case QUERY_BOUNDARY_DRAWCALL:
            drawcallQueue.front().writeEntry();
            drawcallQueue.pop_front();
            break;
        default:
            break;
    }
}

void MetricWriter::writeAll(QueryBoundary boundary) {
    switch (boundary) {
        case QUERY_BOUNDARY_FRAME:
            frameQueue.front().writeHeader();
            while (!frameQueue.empty()) {
                writeQuery(boundary);
            }
            break;
        case QUERY_BOUNDARY_CALL:
            callQueue.front().writeHeader();
            while (!callQueue.empty()) {
                writeQuery(boundary);
            }
            break;
        case QUERY_BOUNDARY_DRAWCALL:
            drawcallQueue.front().writeHeader();
            while (!drawcallQueue.empty()) {
                writeQuery(boundary);
            }
            break;
        default:
            break;
    }
    std::cout << std::endl;
}

std::vector<MetricBackend*>* ProfilerQuery::metricBackends = nullptr;

ProfilerCall::StringTable<int16_t> ProfilerCall::nameTable;
