//
// LDASTools frameCPP - A library implementing the LIGO/Virgo frame
// specification
//
// Copyright (C) 2020 California Institute of Technology
//
// LDASTools frameCPP is free software; you may redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 (GPLv2) of the
// License or at your discretion, any later version.
//
// LDASTools frameCPP is distributed in the hope that it will be useful, but
// without any warranty or even the implied warranty of merchantability
// or fitness for a particular purpose. See the GNU General Public
// License (GPLv2) for more details.
//
// Neither the names of the California Institute of Technology (Caltech),
// The Massachusetts Institute of Technology (M.I.T), The Laser
// Interferometer Gravitational-Wave Observatory (LIGO), nor the names
// of its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// You should have received a copy of the licensing terms for this
// software included in the file LICENSE located in the top-level
// directory of this package. If you did not, you can view a copy at
// http://dcc.ligo.org/M1500244/LICENSE
//

#ifndef FrameCPP_UNIVERSAL__IMPL__FrTOCDataData_HH
#define FrameCPP_UNIVERSAL__IMPL__FrTOCDataData_HH

#include <boost/filesystem.hpp>
#include "ldastoolsal/Logger.hh"
#include <execinfo.h>
#include <cxxabi.h>
#include <memory>
#include <iostream>
#include <atomic>

// Forward declaration to avoid circular dependencies
namespace FrameCPP {
namespace Common {
    struct FrameCPPServices;
}
}

#if defined( __cplusplus )
#if !defined( SWIG )

namespace FrameCPP
{
    namespace Universal
    {
        namespace FrTOCImpl
        {
            class FrTOCDataData
            {
            public:
                struct v4
                {
                    using dt_type = REAL_8;
                    using frame_type = INT_4U;
                    using gtimen_type = INT_4U;
                    using gtimes_type = INT_4U;
                    using localTime_type = INT_4S;
                    using nfirstadc_type = INT_8U;
                    using nfirstmsg_type = INT_8U;
                    using nfirstser_type = INT_8U;
                    using nfirsttable_type = INT_8U;
                    using nFrame_type = INT_4U;
                    using nsh_type = INT_4U;
                    using positionh_type = INT_8U;
                    using runs_type = INT_4S;
                    using shid_type = INT_2U;
                    using shname_type = std::string;
                    using uleaps_type = INT_2S;
                };
                struct v5
                {
                    using data_quality_type = INT_4U;
                    using dt_type = v4::dt_type;
                    using frame_type = v4::frame_type;
                    using gtimen_type = v4::gtimen_type;
                    using gtimes_type = v4::gtimes_type;
                    using namedetector_type = std::string;
                    using ndetector_type = INT_4U;
                    using nfirstadc_type = v4::nfirstadc_type;
                    using nfirstmsg_type = v4::nfirstmsg_type;
                    using nfirstser_type = v4::nfirstser_type;
                    using nfirsttable_type = v4::nfirsttable_type;
                    using nFrame_type = v4::nFrame_type;
                    using nsh_type = v4::nsh_type;
                    using positiondetector_type = INT_8U;
                    using positionh_type = v4::positionh_type;
                    using runs_type = v4::runs_type;
                    using shid_type = v4::shid_type;
                    using shname_type = v4::shname_type;
                    using uleaps_type = v4::uleaps_type;
                };
                using v6 = v5;
                using v7 = v6;
                using v8 = v7;
                struct v9
                {
                    using data_quality_type = v8::data_quality_type;
                    using dt_type = v8::dt_type;
                    using file_base_name_type = std::string;
                    using gtimen_type = v8::gtimen_type;
                    using gtimes_type = v8::gtimes_type;
                    using namedetector_type = v8::namedetector_type;
                    using ndetector_type = v8::ndetector_type;
                    using nFrame_type = v8::nFrame_type;
                    using nsh_type = v8::nsh_type;
                    using positiondetector_type = v8::positiondetector_type;
                    using positionh_type = v8::positionh_type;
                    using shid_type = v8::shid_type;
                    using shname_type = v8::shname_type;
                };
                //-------------------------------------------------------
                using current_version = v9;

                using data_quality_type = current_version::data_quality_type;
                using dt_type = current_version::dt_type;
                using file_base_name_type =
                    current_version::file_base_name_type;
                using gtimen_type = current_version::gtimen_type;
                using gtimes_type = current_version::gtimes_type;
                using namedetector_type = current_version::namedetector_type;
                using ndetector_type = current_version::ndetector_type;
                using nFrame_type = current_version::nFrame_type;
                using nsh_type = current_version::nsh_type;
                using positiondetector_type =
                    current_version::positiondetector_type;
                using positionh_type = current_version::positionh_type;
                using shid_type = current_version::shid_type;
                using shname_type = current_version::shname_type;
                //-------------------------------------------------------
                //-----------------------------------------------------------------
                /// \brief Array of integer QA words from each FrameH
                //-----------------------------------------------------------------
                typedef std::vector< data_quality_type >
                    data_quality_container_type;
                //-----------------------------------------------------------------
                /// \brief Array of frame durations in seconds.
                //-----------------------------------------------------------------
                typedef std::vector< dt_type > dt_container_type;
                //-----------------------------------------------------------------
                /// \brief Array of integer GPS residual nanoseconds for the
                /// frame.
                //-----------------------------------------------------------------
                typedef std::vector< gtimen_type > gtimen_container_type;
                //-----------------------------------------------------------------
                /// \brief Array of integer GPS frame times.
                //-----------------------------------------------------------------
                typedef std::vector< gtimes_type > gtimes_container_type;
                //-----------------------------------------------------------------
                /// \brief Array of FrDetector names.
                //-----------------------------------------------------------------
                typedef std::vector< namedetector_type >
                    namedetector_container_type;
                //-----------------------------------------------------------------
                /// \brief Array of FrDetector positions.
                //-----------------------------------------------------------------
                typedef std::vector< positiondetector_type >
                    positiondetector_container_type;
                //-----------------------------------------------------------------
                /// \brief Array of FrSH IDs.
                //-----------------------------------------------------------------
                typedef std::vector< positionh_type > positionh_container_type;
                //-----------------------------------------------------------------
                /// \brief Array of FrSH IDs.
                //-----------------------------------------------------------------
                typedef std::vector< shid_type > shid_container_type;
                //-----------------------------------------------------------------
                /// \brief Array of FrSH names.
                //-----------------------------------------------------------------
                typedef std::vector< shname_type > shname_container_type;
                //-----------------------------------------------------------------
                /// \brief Array of run numbers.
                ///
                /// Array of run numbers (one per frame).
                /// Size of this array is nFrame.
                /// Available for frame specification versions < 9.
                //-----------------------------------------------------------------
                typedef std::vector< v4::runs_type > runs_container_type;

                //-----------------------------------------------------------------
                /// \brief Retrieve file base name at time of creation
                //-----------------------------------------------------------------
                inline const file_base_name_type&
                GetFileBaseName( ) const
                {
                    return fileBaseName;
                }

                //-----------------------------------------------------------------
                /// \brief Retreive array of integer QA words from each FrameH.
                //-----------------------------------------------------------------
                inline const data_quality_container_type&
                GetDataQuality( ) const
                {
                    return m_dataQuality;
                }

                //-----------------------------------------------------------------
                /// \brief Retrieve array of frame durations in seconds.
                //-----------------------------------------------------------------
                inline const dt_container_type&
                GetDt( ) const
                {
                    return m_dt;
                }

                //-----------------------------------------------------------------
                /// \brief Retrieve array of integer GPS residual nanoseconds
                /// for the frame.
                //-----------------------------------------------------------------
                inline const gtimes_container_type&
                GetGTimeN( ) const
                {
                    return m_GTimeN;
                }

                //-----------------------------------------------------------------
                /// \brief Retrieve array of integer GPS frame times.
                //-----------------------------------------------------------------
                inline const gtimen_container_type&
                GetGTimeS( ) const
                {
                    return m_GTimeS;
                }

                //-----------------------------------------------------------------
                /// \brief
                //-----------------------------------------------------------------
                inline nFrame_type
                GetNFrame( ) const
                {
                    nFrame_type size = GetGTimeS( ).size( );
                    logger_log_debug( logger( ),
                                      20,
                                      "FrTOCDataData::GetNFrame() entry, "
                                      "GetGTimeN.size()=",
                                      size,
                                      " INSTANCE_ID=",
                                      m_instance_id );
                    logger_log_debug(
                        logger( ),
                        30,
                        "FrTOCDataData::GetNFrame() CRITICAL BUG ANALYSIS:" );
                    logger_log_debug(
                        logger( ),
                        30,
                        "FrTOCDataData::GetNFrame() - m_GTimeS vector "
                        "address: ",
                        static_cast< const void* >( &m_GTimeS ) );
                    logger_log_debug(
                        logger( ),
                        30,
                        "FrTOCDataData::GetNFrame() - m_GTimeS capacity: ",
                        m_GTimeS.capacity( ) );

                    if ( size == 0 )
                    {
                        logger_log_debug(
                            logger( ),
                            10,
                            "FrTOCDataData::GetNFrame() PROBLEM FOUND: "
                            "m_GTimeS vector is empty!" );
                        logger_log_debug(
                            logger( ),
                            10,
                            "FrTOCDataData::GetNFrame() This explains why "
                            "GetNumberOfFrames() returns 0 despite TOC Load "
                            "showing nFrame=1" );
                        logger_log_debug(
                            logger( ),
                            10,
                            "FrTOCDataData::GetNFrame() The data from Load() "
                            "was not properly stored in m_dataQuality vector" );
                    }
                    else
                    {
                        logger_log_debug( logger( ),
                                          20,
                                          "FrTOCDataData::GetNFrame() "
                                          "m_GTimeS vector contains ",
                                          size,
                                          " elements" );
                    }

                    return size;
                }

                //-----------------------------------------------------------------
                /// \brief Retrieve array of FrameH positions.
                //-----------------------------------------------------------------
                inline const positionh_container_type&
                GetPositionH( ) const
                {
                    return m_positionH;
                }

                //-----------------------------------------------------------------
                /// \brief Retrieve array of FrSH IDs.
                //-----------------------------------------------------------------
                inline const shid_container_type&
                GetSHid( ) const
                {
                    return m_SHid;
                }

                //-----------------------------------------------------------------
                /// \brief Retrieve array of FrSH names.
                //-----------------------------------------------------------------
                inline const shname_container_type&
                GetSHname( ) const
                {
                    return m_SHname;
                }

                //-----------------------------------------------------------------
                /// \brief Retrieve array of FrDetector names.
                //-----------------------------------------------------------------
                inline const namedetector_container_type&
                GetNameDetector( ) const
                {
                    return m_nameDetector;
                }

                //-----------------------------------------------------------------
                /// \brief Retrieve array of FrDetector positions.
                //-----------------------------------------------------------------
                inline const positiondetector_container_type&
                GetPositionDetector( ) const
                {
                    return m_positionDetector;
                }

                //-----------------------------------------------------------------
                /// \brief Set file base name
                //-----------------------------------------------------------------
                inline void
                SetFileBaseName( const file_base_name_type& Source ) const
                {
                    // ensure that only the filename is captured
                    boost::filesystem::path source_path( Source );
                    fileBaseName = source_path.filename( ).string( );
                }

                //-----------------------------------------------------------------
                /// \brief equality operator
                ///
                /// \param[in] RHS
                ///     The FrTOCData object to be compared.
                ///
                /// \return
                ///     The value true is returned if this object is equivelent
                ///     to the RHS instance; false otherwise.
                //-----------------------------------------------------------------
                inline bool
                operator==( const FrTOCDataData& RHS ) const
                {
#define CMP__( X ) ( X == RHS.X )

                    return (
                        ( &RHS == this ) ||
                        ( ( fileBaseName.compare( RHS.fileBaseName ) == 0 ) &&
                          CMP__( m_dataQuality ) && CMP__( m_GTimeS ) &&
                          CMP__( m_GTimeN ) && CMP__( m_dt ) &&
                          CMP__( m_positionH ) && CMP__( m_SHid ) &&
                          CMP__( m_SHname ) && CMP__( m_nameDetector ) &&
                          CMP__( m_positionDetector ) ) );
#undef CMP__
                }

            protected:
                // Instance tracking for debugging
                static std::atomic<int> s_instance_counter;
                int m_instance_id;
                
            protected:
                /// @brief Print demangled call stack for debugging
                static void print_call_stack() {
                    const int max_frames = 15;
                    void* buffer[max_frames];
                    
                    int nptrs = backtrace(buffer, max_frames);
                    char** strings = backtrace_symbols(buffer, nptrs);
                    
                    if (strings == nullptr) {
                        // Call stack symbols not available
                        return;
                    }
                    
                    // Call stack debugging (output disabled for production)
                    
                    for (int i = 0; i < nptrs; i++) {
                        std::string symbol(strings[i]);
                        std::string demangled_name;
                        
                        // Show raw symbol for debugging
                        // Raw symbol: symbol (output disabled)
                        
                        // Try multiple parsing patterns
                        std::string mangled_name;
                        
                        // Pattern 1: "binary(mangled_name+offset) [address]"
                        size_t start = symbol.find('(');
                        size_t end = symbol.find('+');
                        if (start != std::string::npos && end != std::string::npos && start < end) {
                            mangled_name = symbol.substr(start + 1, end - start - 1);
                        } 
                        // Pattern 2: "binary(mangled_name) [address]" (no offset)
                        else if (start != std::string::npos) {
                            size_t close = symbol.find(')', start);
                            if (close != std::string::npos) {
                                mangled_name = symbol.substr(start + 1, close - start - 1);
                            }
                        }
                        
                        // Try to demangle if we found a mangled name
                        if (!mangled_name.empty() && mangled_name.find("_Z") == 0) {
                            int status = 0;
                            char* demangled = abi::__cxa_demangle(mangled_name.c_str(), nullptr, nullptr, &status);
                            
                            if (status == 0 && demangled) {
                                demangled_name = demangled;
                                free(demangled);
                            } else {
                                demangled_name = mangled_name;
                            }
                        } else {
                            demangled_name = mangled_name.empty() ? symbol : mangled_name;
                        }
                        
                        // Demangled symbol: demangled_name (output disabled)
                    }
                    
                    free(strings);
                }

                /// @brief Get the logger for FrTOCData debugging
                /// 
                /// DEPRECATED: This static method will be replaced with dependency injection.
                /// New code should pass FrameCPPServices and call services.getLogger("framecpp.frtoc.data")
                /// 
                /// @return Static logger instance (thread-safe, lazy initialization)
                /// Moved to FrTOCData.cc to avoid ODR violations from function-local statics
                static SimpleLogger* logger();

                /// @brief Get the logger for FrTOCData debugging (dependency injection version)
                /// 
                /// This is the preferred way to get loggers using explicit dependency injection
                /// following Muldoon's principles. Eventually the static logger() method above
                /// will be removed.
                /// 
                /// @param services FrameCPP services context containing logger manager
                /// @return Logger instance (owned by LoggerManager in services)
                /// @thread_safety Thread-safe
                static SimpleLogger* logger( const FrameCPP::Common::FrameCPPServices& services );

            public:
                /// @brief Default constructor with debugging
                FrTOCDataData( ) : m_instance_id(++s_instance_counter)
                {
                    logger_log_debug( logger( ),
                                      30,
                                      "FrTOCDataData::FrTOCDataData() DEFAULT "
                                      "constructor, this=",
                                      static_cast< const void* >( this ),
                                      " INSTANCE_ID=", m_instance_id );
                    logger_log_debug(
                        logger( ),
                        30,
                        "FrTOCDataData::FrTOCDataData() m_dataQuality address=",
                        static_cast< const void* >( &m_dataQuality ) );
                }

                /// @brief Copy constructor with enhanced debugging
                FrTOCDataData( const FrTOCDataData& other )
                    : m_instance_id(++s_instance_counter),
                      m_dataQuality( other.m_dataQuality ),
                      m_GTimeS( other.m_GTimeS ), m_GTimeN( other.m_GTimeN ),
                      m_dt( other.m_dt ),
                      m_positionDetector( other.m_positionDetector ),
                      m_positionH( other.m_positionH ),
                      m_nameDetector( other.m_nameDetector ),
                      m_SHid( other.m_SHid ), m_SHname( other.m_SHname ),
                      m_runs( other.m_runs )
                {
                    logger_log_debug( logger( ),
                                      15,
                                      "FrTOCDataData::FrTOCDataData() COPY "
                                      "constructor ENTRY, this=",
                                      static_cast< const void* >( this ),
                                      " from=",
                                      static_cast< const void* >( &other ),
                                      " MY_ID=", m_instance_id,
                                      " OTHER_ID=", other.m_instance_id );
                    
                    // Critical data transfer analysis
                    logger_log_debug( logger( ),
                                      10,
                                      "COPY CONSTRUCTOR: source m_dataQuality.size()=",
                                      other.m_dataQuality.size( ),
                                      " capacity=",
                                      other.m_dataQuality.capacity() );
                    logger_log_debug( logger( ),
                                      10,
                                      "COPY CONSTRUCTOR: destination m_dataQuality.size()=",
                                      m_dataQuality.size( ),
                                      " capacity=",
                                      m_dataQuality.capacity() );
                    logger_log_debug(
                        logger( ),
                        20,
                        "COPY CONSTRUCTOR: source m_dataQuality address=",
                        static_cast< const void* >( &other.m_dataQuality ),
                        " destination address=",
                        static_cast< const void* >( &m_dataQuality ) );

                    // Identify if this is the problematic copy that loses data
                    if ( other.m_dataQuality.size( ) > 0 && 
                         m_dataQuality.size( ) != other.m_dataQuality.size( ) )
                    {
                        logger_log_debug( logger( ),
                                          5,
                                          "CRITICAL: Copy constructor data size mismatch detected!" );
                        logger_log_debug( logger( ),
                                          5,
                                          "CRITICAL: This may be the copy that loses frame data!" );
                        // Print call stack to identify where this problematic copy occurs
                        print_call_stack( );
                    }
                    else if ( other.m_dataQuality.size( ) > 0 )
                    {
                        logger_log_debug( logger( ),
                                          15,
                                          "COPY CONSTRUCTOR: Data transfer successful, sizes match" );
                        // Show first data element if available
                        if ( m_dataQuality.size( ) > 0 )
                        {
                            logger_log_debug( logger( ),
                                              20,
                                              "COPY CONSTRUCTOR: First data element copied: source=",
                                              other.m_dataQuality[0],
                                              " destination=",
                                              m_dataQuality[0] );
                        }
                    }
                    else
                    {
                        logger_log_debug( logger( ),
                                          20,
                                          "COPY CONSTRUCTOR: Source has no data (normal for empty constructor)" );
                    }
                    
                    logger_log_debug( logger( ),
                                      15,
                                      "FrTOCDataData::FrTOCDataData() COPY constructor COMPLETE" );
                }

                /// @brief Move constructor with enhanced debugging
                FrTOCDataData( FrTOCDataData&& other ) noexcept
                    : m_instance_id(++s_instance_counter),
                      m_dataQuality( std::move( other.m_dataQuality ) ),
                      m_GTimeS( std::move( other.m_GTimeS ) ),
                      m_GTimeN( std::move( other.m_GTimeN ) ),
                      m_dt( std::move( other.m_dt ) ),
                      m_positionDetector(
                          std::move( other.m_positionDetector ) ),
                      m_positionH( std::move( other.m_positionH ) ),
                      m_nameDetector( std::move( other.m_nameDetector ) ),
                      m_SHid( std::move( other.m_SHid ) ),
                      m_SHname( std::move( other.m_SHname ) ),
                      m_runs( std::move( other.m_runs ) )
                {
                    logger_log_debug( logger( ),
                                      15,
                                      "FrTOCDataData::FrTOCDataData() MOVE "
                                      "constructor ENTRY, this=",
                                      static_cast< const void* >( this ),
                                      " from=",
                                      static_cast< const void* >( &other ),
                                      " MY_ID=", m_instance_id,
                                      " OTHER_ID=", other.m_instance_id );
                    
                    // Move constructor should transfer data efficiently
                    logger_log_debug( logger( ),
                                      10,
                                      "MOVE CONSTRUCTOR: destination m_dataQuality.size()=",
                                      m_dataQuality.size( ),
                                      " capacity=",
                                      m_dataQuality.capacity() );
                    logger_log_debug( logger( ),
                                      10,
                                      "MOVE CONSTRUCTOR: source m_dataQuality.size() after move=",
                                      other.m_dataQuality.size( ) );
                    logger_log_debug(
                        logger( ),
                        20,
                        "MOVE CONSTRUCTOR: destination m_dataQuality address=",
                        static_cast< const void* >( &m_dataQuality ) );
                        
                    // Show first data element if available
                    if ( m_dataQuality.size( ) > 0 )
                    {
                        logger_log_debug( logger( ),
                                          20,
                                          "MOVE CONSTRUCTOR: First data element moved: ",
                                          m_dataQuality[0] );
                    }
                    
                    logger_log_debug( logger( ),
                                      15,
                                      "FrTOCDataData::FrTOCDataData() MOVE constructor COMPLETE" );
                }

                /// @brief Assignment operator with full debugging
                FrTOCDataData& operator=(const FrTOCDataData& other) {
                    logger_log_debug(logger(), 5, 
                                   "FrTOCDataData::operator= ASSIGNMENT ENTRY, this=",
                                   static_cast<const void*>(this),
                                   " from=", static_cast<const void*>(&other),
                                   " MY_ID=", m_instance_id,
                                   " OTHER_ID=", other.m_instance_id);
                    
                    if (this != &other) {
                        logger_log_debug(logger(), 5,
                                       "ASSIGNMENT: source m_dataQuality.size()=",
                                       other.m_dataQuality.size());

                        // Perform assignment
                        fileBaseName = other.fileBaseName;  // FIX: Copy fileBaseName too!
                        m_dataQuality = other.m_dataQuality;
                        m_GTimeS = other.m_GTimeS;
                        m_GTimeN = other.m_GTimeN;
                        m_dt = other.m_dt;
                        m_positionDetector = other.m_positionDetector;
                        m_positionH = other.m_positionH;
                        m_nameDetector = other.m_nameDetector;
                        m_SHid = other.m_SHid;
                        m_SHname = other.m_SHname;
                        m_runs = other.m_runs;
                        // Note: m_instance_id stays the same - object identity doesn't change
                        
                        logger_log_debug(logger(), 5, 
                                       "ASSIGNMENT: result m_dataQuality.size()=", 
                                       m_dataQuality.size());
                        
                        if (other.m_dataQuality.size() > 0 && 
                            m_dataQuality.size() != other.m_dataQuality.size()) {
                            logger_log_debug(logger(), 5, 
                                           "CRITICAL: Assignment operator data size mismatch!");
                            print_call_stack();
                        }
                    } else {
                        logger_log_debug(logger(), 5, "ASSIGNMENT: Self-assignment, no-op");
                    }
                    
                    logger_log_debug(logger(), 5, "FrTOCDataData::operator= ASSIGNMENT COMPLETE");
                    return *this;
                }
                
                /// @brief Move assignment operator with debugging
                FrTOCDataData& operator=(FrTOCDataData&& other) noexcept {
                    logger_log_debug(logger(), 5, 
                                   "FrTOCDataData::operator= MOVE ASSIGNMENT ENTRY, this=",
                                   static_cast<const void*>(this),
                                   " from=", static_cast<const void*>(&other),
                                   " MY_ID=", m_instance_id,
                                   " OTHER_ID=", other.m_instance_id);
                    
                    if (this != &other) {
                        logger_log_debug(logger(), 5,
                                       "MOVE ASSIGNMENT: source m_dataQuality.size()=",
                                       other.m_dataQuality.size());

                        // Perform move assignment
                        fileBaseName = std::move(other.fileBaseName);  // FIX: Move fileBaseName too!
                        m_dataQuality = std::move(other.m_dataQuality);
                        m_GTimeS = std::move(other.m_GTimeS);
                        m_GTimeN = std::move(other.m_GTimeN);
                        m_dt = std::move(other.m_dt);
                        m_positionDetector = std::move(other.m_positionDetector);
                        m_positionH = std::move(other.m_positionH);
                        m_nameDetector = std::move(other.m_nameDetector);
                        m_SHid = std::move(other.m_SHid);
                        m_SHname = std::move(other.m_SHname);
                        m_runs = std::move(other.m_runs);
                        // Note: m_instance_id stays the same
                        
                        logger_log_debug(logger(), 5, 
                                       "MOVE ASSIGNMENT: result m_dataQuality.size()=", 
                                       m_dataQuality.size());
                    } else {
                        logger_log_debug(logger(), 5, "MOVE ASSIGNMENT: Self-assignment, no-op");
                    }
                    
                    logger_log_debug(logger(), 5, "FrTOCDataData::operator= MOVE ASSIGNMENT COMPLETE");
                    return *this;
                }

                /// @brief Destructor with debugging
                ~FrTOCDataData( )
                {
                    logger_log_debug(
                        logger( ),
                        30,
                        "FrTOCDataData::~FrTOCDataData() destructor, this=",
                        static_cast< const void* >( this ),
                        " INSTANCE_ID=", m_instance_id );
                    logger_log_debug(
                        logger( ),
                        30,
                        "FrTOCDataData::~FrTOCDataData() m_dataQuality.size()=",
                        m_dataQuality.size( ) );
                }



                /// @brief Helper class for dual-format checksum logging
                /// (decimal and hex) Maintains lazy formatting by deferring
                /// conversion until stream insertion
                template < typename T >
                struct ChecksumFormatter
                {
                    const T& value;
                    explicit ChecksumFormatter( const T& val ) : value( val )
                    {
                    }

                    friend std::ostream&
                    operator<<( std::ostream& os, const ChecksumFormatter& cf )
                    {
                        return os << cf.value << " (0x" << std::hex << cf.value
                                  << std::dec << ")";
                    }
                };

                /// @brief Convenience function to create checksum formatter
                /// @param value Checksum value to format
                /// @return ChecksumFormatter that will format as "decimal
                /// (0xhex)"
                template < typename T >
                static ChecksumFormatter< T >
                pretty_print_checksum( const T& value )
                {
                    return ChecksumFormatter< T >( value );
                }

                //-----------------------------------------------------------------
                /// \brief The name of the file at the time of creation.
                //-----------------------------------------------------------------
                mutable file_base_name_type fileBaseName;
                //-----------------------------------------------------------------
                /// \brief Array of integer QA words from each FrameH (size of
                /// nFrame)
                //-----------------------------------------------------------------
                data_quality_container_type m_dataQuality;
                //-----------------------------------------------------------------
                /// \brief Array of integer GPS frame times (size of nFrame).
                //-----------------------------------------------------------------
                gtimes_container_type m_GTimeS;
                //-----------------------------------------------------------------
                /// \brief Array of integer GPS residual nanoseconds for the
                /// frame (size of nFrame).
                //-----------------------------------------------------------------
                gtimen_container_type m_GTimeN;
                //-----------------------------------------------------------------
                /// \brief Array of frame durations in seconds (size of nFrame).
                //-----------------------------------------------------------------
                dt_container_type m_dt;
                //-----------------------------------------------------------------
                /// \brief Array of FrDetector positions.
                ///
                /// Array of FrDetector positions from the beginning of
                /// file.
                /// The size of array is specified by nDetector.
                ///
                /// \note
                /// Only the first occurrence for each type of FrDetector
                /// is captured.
                //-----------------------------------------------------------------
                positiondetector_container_type m_positionDetector;
                //-----------------------------------------------------------------
                /// \brief
                ///
                /// Array of FrameH positions, in bytes,
                /// from beginning of file.
                /// The size of this array is specified by nFrame.
                //-----------------------------------------------------------------
                positionh_container_type m_positionH;
                //-----------------------------------------------------------------
                /// \brief Array of FrDetector names.
                ///
                /// The size of this array is specified by nDetector.
                /// They appear alphabetically.
                //-----------------------------------------------------------------
                namedetector_container_type m_nameDetector;
                //-----------------------------------------------------------------
                /// \brief Array of FrSH IDs.
                ///
                /// Array of FrSH IDs.
                /// The size of this array is specified by nSH.
                //-----------------------------------------------------------------
                shid_container_type m_SHid;
                //-----------------------------------------------------------------
                /// \brief
                ///
                /// Array of FrSH names.
                /// The size of array is specified by nSH.
                //-----------------------------------------------------------------
                shname_container_type m_SHname;
                //-----------------------------------------------------------------
                /// \brief Array of run numbers.
                ///
                /// Array of run numbers, one per frame (size of nFrame).
                /// Only populated for frame specification versions < 9.
                /// For v9+, this remains empty as run indexing was deprecated.
                //-----------------------------------------------------------------
                runs_container_type m_runs;
            };
        } // namespace FrTOCImpl
    } // namespace Universal
} // namespace FrameCPP
#endif /* !defined( SWIG ) */
#endif /* defined( __cplusplus ) */

#endif /* FrameCPP_UNIVERSAL__IMPL__FrTOCDataData_HH */
