//
// LDASTools frameCPP - A library implementing the LIGO/Virgo frame
// specification
//
// Copyright (C) 2025 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__FrTOCDataSerialIO_HH
#define FrameCPP_UNIVERSAL__IMPL__FrTOCDataSerialIO_HH

#if !defined( SWIGIMPORTED )
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/split_member.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/version.hpp>

#include "framecpp/Common/FrameSpec.hh"
#include "framecpp/Universal/impl/HelperSerialIO.hh"
#endif /* !defined( SWIGIMPORTED ) */

#include "framecpp/Universal/impl/FrTOCDataData.hh"

#if !defined( SWIGIMPORTED )
namespace FrameCPP
{
    namespace Universal
    {
        namespace FrTOCImpl
        {
            /// \brief Serialization I/O implementation for FrTOCData structures
            ///
            /// This class provides versioned serialization support for
            /// FrTOCData objects using Boost.Serialization. It handles the
            /// Table of Contents data structure that contains frame metadata
            /// and positioning information across different frame specification
            /// versions (v4 through v9).
            ///
            /// \note FrTOCData was introduced in v4 of the frame specification
            class FrTOCDataSerialIO : public virtual FrTOCDataData
            {
            public:
                /// \brief Default constructor
                ///
                /// Constructs an empty SerialIO object ready for serialization
                /// operations. The object inherits data members from the
                /// FrTOCDataData base class.
                FrTOCDataSerialIO( )
                {
                }

            private:
                friend class boost::serialization::access;

                /// \brief Serialize FrTOCData to/from an archive
                ///
                /// This method serializes the FrTOCData to a serialization archive,
                /// handling the frame metadata and positioning arrays.
                ///
                /// \tparam Archive The Boost.Serialization archive type
                ///
                /// \param[in,out] ar The archive to read/write data
                /// \param[in] version The target serialization version (4-9)
                ///
                /// \throws boost::archive::archive_exception on serialization
                /// errors
                ///
                /// Version-specific handling:
                /// - v4: Basic frame metadata (times, positions, detector info)
                /// - v5: Adds data quality and detector positioning
                /// - v9: Adds file base name, removes some legacy fields
                ///
                /// \note Multiple arrays of frame metadata are serialized
                /// \note Field evolution handled across frame specification
                /// versions
                template < class Archive >
                void
                serialize( Archive& ar, const unsigned int version )
                {
                    using boost::serialization::make_nvp;

                    if ( version >= 4 )
                    {
                        // Basic frame timing and positioning arrays
                        ar& make_nvp( "m_GTimeS", m_GTimeS ) &
                            make_nvp( "m_GTimeN", m_GTimeN ) &
                            make_nvp( "m_dt", m_dt ) &
                            make_nvp( "m_positionH", m_positionH ) &
                            make_nvp( "m_SHid", m_SHid ) &
                            make_nvp( "m_SHname", m_SHname );

                        // Data quality array (v5+)
                        if ( version >= 5 )
                        {
                            ar& make_nvp( "m_dataQuality", m_dataQuality ) &
                                make_nvp( "m_nameDetector", m_nameDetector ) &
                                make_nvp( "m_positionDetector",
                                          m_positionDetector );
                        }

                        // File base name (v9+)
                        if ( version >= 9 )
                        {
                            ar& make_nvp( "fileBaseName", fileBaseName );
                        }
                    }
                }
            };

        } // namespace FrTOCImpl
    } // namespace Universal
} // namespace FrameCPP

/// \brief Specify the class version for Boost.Serialization
///
/// This macro tells Boost.Serialization that FrTOCDataData is at version 9,
/// which corresponds to the v9 frame specification. The serialization framework
/// uses this version number to determine how to serialize/deserialize the data.
///
/// \note This version number is passed to the save() and load() methods
BOOST_CLASS_VERSION( FrameCPP::Universal::FrTOCImpl::FrTOCDataData, 9 )

#endif /* !defined( SWIGIMPORTED ) */

#endif /* FrameCPP_UNIVERSAL__IMPL__FrTOCDataSerialIO_HH */
