//
// Diagnostic test to pinpoint FrameH serialization failure
//

#include <iostream>
#include <sstream>
#include <exception>

#include <boost/shared_ptr.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/nvp.hpp>

#include "framecpp/FrameH.hh"
#include "framecpp/FrDetector.hh"
#include "framecpp/FrVect.hh"
#include "framecpp/FrProcData.hh"

int main()
{
    using FrameCPP::FrameH;
    using FrameCPP::FrDetector;
    using FrameCPP::FrProcData;
    using FrameCPP::FrVect;

    try
    {
        std::cout << "Creating FrameH object..." << std::endl;
        FrameH source_obj;

        std::cout << "Adding detector..." << std::endl;
        auto detector = boost::shared_ptr< FrDetector >( new FrDetector( ) );
        source_obj.RefDetectSim( ).append( detector );
        std::cout << "  Detector added, count: " << source_obj.RefDetectSim( ).size( ) << std::endl;

        std::cout << "Adding auxiliary data..." << std::endl;
        FrVect::dimension_type auxDim( 1024, 1.0 );
        auto                   auxVect =
            boost::shared_ptr< FrVect >( new FrVect( "H1:TEST_AUX",
                                                     FrVect::FR_VECT_8R,
                                                     1,
                                                     &auxDim,
                                                     "V" ) );
        source_obj.RefAuxData( ).append( auxVect );
        std::cout << "  AuxData added, count: " << source_obj.RefAuxData( ).size( ) << std::endl;

        std::cout << "Adding processed data..." << std::endl;
        auto proc = boost::shared_ptr< FrProcData >(
            new FrProcData( "H1:TEST_PROC",
                            "Test proc",
                            FrProcData::TIME_SERIES,
                            0, 0, 1, 0, 0, 0, 0 ) );
        source_obj.RefProcData( ).append( proc );
        std::cout << "  ProcData added, count: " << source_obj.RefProcData( ).size( ) << std::endl;

        // Serialize
        std::cout << "\n=== SERIALIZATION PHASE ===" << std::endl;
        std::stringstream buffer;
        {
            std::cout << "Creating output archive..." << std::endl;
            boost::archive::text_oarchive output{ buffer };

            std::cout << "Serializing FrameH..." << std::endl;
            output << boost::serialization::make_nvp( "FrameH", source_obj );

            std::cout << "Serialization complete! Buffer size: " << buffer.str().size() << " bytes" << std::endl;
        }

        // Show first 500 chars of serialized data
        std::string serialized = buffer.str();
        std::cout << "\nFirst 500 chars of serialized data:\n"
                  << serialized.substr(0, std::min(size_t(500), serialized.size()))
                  << "\n..." << std::endl;

        // Deserialize
        std::cout << "\n=== DESERIALIZATION PHASE ===" << std::endl;
        FrameH loaded_obj;
        {
            std::cout << "Creating input archive..." << std::endl;
            boost::archive::text_iarchive input{ buffer };

            std::cout << "Deserializing FrameH..." << std::endl;
            try
            {
                input >> boost::serialization::make_nvp( "FrameH", loaded_obj );
                std::cout << "Deserialization SUCCESS!" << std::endl;
            }
            catch( const boost::archive::archive_exception& e )
            {
                std::cerr << "BOOST ARCHIVE EXCEPTION during deserialization:" << std::endl;
                std::cerr << "  what(): " << e.what() << std::endl;
                std::cerr << "  code: " << e.code << std::endl;
                return 1;
            }
            catch( const std::exception& e )
            {
                std::cerr << "STD EXCEPTION during deserialization:" << std::endl;
                std::cerr << "  what(): " << e.what() << std::endl;
                return 1;
            }
        }

        // Verify
        std::cout << "\n=== VERIFICATION PHASE ===" << std::endl;
        std::cout << "Loaded DetectSim count: " << loaded_obj.RefDetectSim( ).size( ) << std::endl;
        std::cout << "Loaded AuxData count: " << loaded_obj.RefAuxData( ).size( ) << std::endl;
        std::cout << "Loaded ProcData count: " << loaded_obj.RefProcData( ).size( ) << std::endl;

        std::cout << "\n✓ TEST PASSED!" << std::endl;
        return 0;
    }
    catch( const std::exception& e )
    {
        std::cerr << "\nUNEXPECTED EXCEPTION:" << std::endl;
        std::cerr << "  what(): " << e.what() << std::endl;
        return 1;
    }
}
