//
// LDASTools frameCPP - A library implementing the LIGO/Virgo frame
// specification
//
// Copyright (C) 2018 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
//

#include <iostream>
#include <sstream>

#include "framecpp_config.h"

#include "ldastoolsal/Logger.hh"

#include "framecpp/FrameCPP.hh"
#include "framecpp/IFrameStream.hh"
#include "framecpp/Universal/VersionRegistry.hh"
#include "framecpp/Version9/FrameSpec.hh"

// DetectorNameTable is defined in src/Universal/FrDetector.cc
// Removed duplicate definition here to fix ODR violation detected by ASAN
// Previously was: const Common::DetectorNames& DetectorNameTable = Version_9::DetectorNameTable;

//-----------------------------------------------------------------------------
// The time information that is returned by this function is based on when the
// top level configure.in ( ldas/configure.in) file was committed to CVS.
// The time value is in UTC time as that is what CVS uses internally.
//
//! return: std::string - The string representation of the cvs date
std::string
FrameCPP::GetCVSDate( )
{
    return "Source is under GIT";
}

//-----------------------------------------------------------------------------
//! return: std::string - The string representation of when the library was
//+ built
std::string
FrameCPP::GetBuildDate( )
{
    return FRAMECPP_BUILD_DATE;
}

//! return: INT_2U - current minor version for the frame library
INT_2U
FrameCPP::GetFrameLibraryMinorVersion( )
{
    return FrameCPP::Version::LIBRARY_MINOR_VERSION;
}

void
FrameCPP::Initialize( )
{
    // Initialize all frame specification versions via VersionRegistry
    // This is idempotent - calling multiple times is safe
    Universal::VersionRegistry::init_all_versions();
}

// Implementation of IFrameFStream static logger method
SimpleLogger* FrameCPP::IFrameFStream::logger() {
    static SimpleLogger* instance = get_channel_logger("framecpp.iframe");
    return instance;
}

// Automatic initialization via static initializer
// This ensures all frame specifications are initialized when the library loads
namespace {
    struct AutoInitializer {
        AutoInitializer() {
            FrameCPP::Initialize();
        }
    };
    static AutoInitializer auto_init;
}

// Additional initialization hook using __attribute__((constructor))
// This ensures initialization even with static libraries
#if defined(__GNUC__) || defined(__clang__)
static void __attribute__((constructor)) framecpp_library_init() {
    FrameCPP::Initialize();
}
#endif
