/*========================== begin_copyright_notice ============================

Copyright (C) 2019-2026 Intel Corporation

SPDX-License-Identifier: MIT

============================= end_copyright_notice ===========================*/

//     File Name:  md_calculation.h
//
//     Abstract:   C++ metrics discovery metrics calculation features header.

#pragma once

#include "metrics_discovery_api.h"

#include <stack>

#define MD_SAVED_REPORT_NUMBER 0xFFFFFFFF

using namespace MetricsDiscovery;

namespace MetricsDiscoveryInternal
{
    // Forward declarations //
    class CMetricsDevice;
    class CMetricSet;
    class CEquation;
    class CMetricsCalculator;

    ///////////////////////////////////////////////////////////////////////////////
    // Common calculation context:
    //////////////////////////////////////////////////////////////////////////////
    typedef struct SCommonCalculationContext
    {
        // MetricsCalculator
        CMetricsCalculator* Calculator; // Required

        // ConcurrentGroup and MetricSet
        IConcurrentGroupLatest* ConcurrentGroup;
        CMetricSet*             MetricSet; // Required
        uint32_t                MetricsAndInformationCount;

        // Input
        const uint8_t* RawData;        // Required
        uint32_t       RawReportCount; // Required
        uint32_t       RawReportSize;

        // Output
        TTypedValue_1_0* Out; // Required
        uint32_t         OutReportCount;
        TTypedValue_1_0* OutMaxValues;

        // Calculation
        TTypedValue_1_0* DeltaValues; // Required

        // Aggregation
        bool AggregationEnabled;

    } TCommonCalculationContext;

    ///////////////////////////////////////////////////////////////////////////////
    // Stream specific calculation context:
    //////////////////////////////////////////////////////////////////////////////
    typedef struct SStreamCalculationContext : public TCommonCalculationContext
    {
        // MetricSet
        int32_t ContextIdIdx;
        int32_t ReportReasonIdx;

        // ContextFiltering
        bool DoContextFiltering; // Required - not supported

        // Calculation
        const uint8_t* PrevRawDataPtr;
        uint32_t       PrevRawReportNumber;
        const uint8_t* LastRawDataPtr;
        uint32_t       LastRawReportNumber;

    } TStreamCalculationContext;

    ///////////////////////////////////////////////////////////////////////////////
    // Query specific calculation context:
    //////////////////////////////////////////////////////////////////////////////
    typedef struct SQueryCalculationContext : public TCommonCalculationContext
    {
    } TQueryCalculationContext;

    ///////////////////////////////////////////////////////////////////////////////
    // Union with all of calculation contexts:
    //////////////////////////////////////////////////////////////////////////////
    typedef union SCalculationContext
    {
        TCommonCalculationContext CommonCalculationContext;
        TStreamCalculationContext StreamCalculationContext;
        TQueryCalculationContext  QueryCalculationContext;
    } TCalculationContext;

    //////////////////////////////////////////////////////////////////////////////
    //
    // Class:
    //     CCalculationManager
    //
    // Description:
    //     Base pure virtual class used for calculations.
    //
    //////////////////////////////////////////////////////////////////////////////
    class CCalculationManager
    {
    public:
        virtual ~CCalculationManager() {};

        // Calculation.
        virtual void            ResetContext( TCalculationContext& context )             = 0;
        virtual TCompletionCode PrepareContext( TCalculationContext& context )           = 0;
        virtual bool            CalculateNextReport( TCalculationContext& context )      = 0;
        virtual bool            CalculateNextAsyncReport( TCalculationContext& context ) = 0;
    };

    //////////////////////////////////////////////////////////////////////////////
    //
    // Class:
    //     CMetricsCalculationManager
    //
    // Description:
    //     Template class used for complete metrics calculations.
    //
    //////////////////////////////////////////////////////////////////////////////
    template <TMeasurementType measurementType>
    class CMetricsCalculationManager : public CCalculationManager
    {
    public:
        // Calculation.
        virtual void            ResetContext( TCalculationContext& context ) final;
        virtual TCompletionCode PrepareContext( TCalculationContext& context ) final;
        virtual bool            CalculateNextReport( TCalculationContext& context ) final;
        virtual bool            CalculateNextAsyncReport( TCalculationContext& context ) final;

    private:
        int32_t GetInformationIndex( const char* symbolName, CMetricSet* set );
        void    ProcessCalculation( TStreamCalculationContext* sc, bool async, uint32_t adapterId );
    };
} // namespace MetricsDiscoveryInternal
