//
// Copyright © 2019 Arm Ltd. All rights reserved.
// SPDX-License-Identifier: MIT
//

#include "PeriodicCounterCapture.hpp"

#include <common/include/Logging.hpp>

#include <iostream>

namespace arm
{

namespace pipe
{

void PeriodicCounterCapture::Start()
{
    // Check if the capture thread is already running
    if (m_IsRunning)
    {
        // The capture thread is already running
        return;
    }

    // Mark the capture thread as running
    m_IsRunning = true;

    // Keep the capture procedure going until the capture thread is signalled to stop
    m_KeepRunning.store(true);

    // Start the new capture thread.
    m_PeriodCaptureThread = std::thread(&PeriodicCounterCapture::Capture, this, std::ref(m_ReadCounterValues));
}

void PeriodicCounterCapture::Stop()
{
    // Signal the capture thread to stop
    m_KeepRunning.store(false);

    // Check that the capture thread is running
    if (m_PeriodCaptureThread.joinable())
    {
        // Wait for the capture thread to complete operations
        m_PeriodCaptureThread.join();
    }

    // Mark the capture thread as not running
    m_IsRunning = false;
}

CaptureData PeriodicCounterCapture::ReadCaptureData()
{
    return m_CaptureDataHolder.GetCaptureData();
}

void PeriodicCounterCapture::DispatchPeriodicCounterCapturePacket(
    const std::string& backendId, const std::vector<Timestamp>& timestampValues)
{
    // Report counter values
    for (const auto& timestampInfo : timestampValues)
    {
        std::vector<CounterValue> backendCounterValues = timestampInfo.counterValues;
        for_each(backendCounterValues.begin(), backendCounterValues.end(), [&](CounterValue& backendCounterValue)
        {
            // translate the counterId to globalCounterId
            backendCounterValue.counterId = m_CounterIdMap.GetGlobalId(backendCounterValue.counterId, backendId);
        });

        // Send Periodic Counter Capture Packet for the Timestamp
        m_SendCounterPacket.SendPeriodicCounterCapturePacket(timestampInfo.timestamp, backendCounterValues);
    }
}

void PeriodicCounterCapture::Capture(IReadCounterValues& readCounterValues)
{
    do
    {
        // Check if the current capture data indicates that there's data capture
        auto currentCaptureData = ReadCaptureData();
        const std::vector<uint16_t>& counterIds = currentCaptureData.GetCounterIds();
        const uint32_t capturePeriod = currentCaptureData.GetCapturePeriod();

        if (capturePeriod == 0)
        {
            // No data capture, wait the indicated capture period (milliseconds), if it is not zero
            std::this_thread::sleep_for(std::chrono::milliseconds(50u));
            continue;
        }

        if(counterIds.size() != 0)
        {
            std::vector<CounterValue> counterValues;

            auto numCounters = counterIds.size();
            counterValues.reserve(numCounters);

            // Create a vector of pairs of CounterIndexes and Values
            for (uint16_t index = 0; index < numCounters; ++index)
            {
                auto requestedId = counterIds[index];
                uint32_t counterValue = 0;
                try
                {
                    counterValue = readCounterValues.GetDeltaCounterValue(requestedId);
                }
                catch (const arm::pipe::ProfilingException& e)
                {
                    // Report the error and continue
                    ARM_PIPE_LOG(warning) << "An error has occurred when getting a counter value: "
                                       << e.what();
                    continue;
                }

                counterValues.emplace_back(CounterValue {requestedId, counterValue });
            }

            // Send Periodic Counter Capture Packet for the Timestamp
            m_SendCounterPacket.SendPeriodicCounterCapturePacket(GetTimestamp(), counterValues);
        }

        // Report counter values for each active backend
        auto activeBackends = currentCaptureData.GetActiveBackends();
        for_each(activeBackends.begin(), activeBackends.end(), [&](const std::string& backendId)
        {
            DispatchPeriodicCounterCapturePacket(
                backendId, m_BackendProfilingContexts.at(backendId)->ReportCounterValues());
        });

        // Wait the indicated capture period (microseconds)
        std::this_thread::sleep_for(std::chrono::microseconds(capturePeriod));
    }
    while (m_KeepRunning.load());
}

} // namespace pipe

} // namespace arm
