//
// 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
//

#include "framecpp/FrameDebugPrint.hh"

#if !defined( SWIGIMPORTED )

namespace FrameCPP
{
    namespace Debug
    {
        //=================================================================
        // FramePrinter Implementation
        //=================================================================

        FramePrinter::FramePrinter( std::ostream& os ) : m_os( os ), m_field_filter( nullptr ), m_value_transformer( nullptr ), m_services( nullptr )
        {
        }
        
        FramePrinter::FramePrinter( std::ostream& os, const FrameCPP::Common::FrameCPPServices& services )
            : m_os( os ), m_field_filter( nullptr ), m_value_transformer( nullptr ), m_services( &services )
        {
        }

        FramePrinter&
        FramePrinter::setVersion( unsigned int ver )
        {
            version = ver;
            return *this;
        }

        FramePrinter&
        FramePrinter::setAlignment( AlignmentMode mode )
        {
            alignment = mode;
            return *this;
        }

        FramePrinter&
        FramePrinter::setSeparator( const std::string& sep )
        {
            separator = sep;
            return *this;
        }

        FramePrinter&
        FramePrinter::setIndentation( int spaces )
        {
            indentation = spaces;
            return *this;
        }

        FramePrinter&
        FramePrinter::showTypeInfo( bool show )
        {
            show_type_info = show;
            return *this;
        }

        FramePrinter&
        FramePrinter::showVersionInfo( bool show )
        {
            show_version_info = show;
            return *this;
        }

        FramePrinter&
        FramePrinter::setMaxFieldWidth( size_t width )
        {
            max_field_width = width;
            return *this;
        }

        FramePrinter&
        FramePrinter::setMaxValueWidth( size_t width )
        {
            max_value_width = width;
            return *this;
        }

        FramePrinter&
        FramePrinter::setFieldFilter( const FieldFilter* filter )
        {
            m_field_filter = filter;
            return *this;
        }

        FramePrinter&
        FramePrinter::setValueTransformer( const ValueTransformer* transformer )
        {
            m_value_transformer = transformer;
            return *this;
        }

        FramePrinter&
        FramePrinter::setOutputFormat( OutputFormat format )
        {
            output_format = format;
            return *this;
        }

        FramePrinter&
        FramePrinter::setWalkObjects( bool walk )
        {
            walk_objects = walk;
            return *this;
        }

        FramePrinter&
        FramePrinter::setWalkContainers( bool walk_containers_flag )
        {
            walk_containers = walk_containers_flag;
            return *this;
        }

        FramePrinter&
        FramePrinter::setWalkDepth( int depth )
        {
            walk_depth = depth;
            return *this;
        }

        //=================================================================
        // Convenience Factory Functions
        //=================================================================

        FramePrinter
        compactPrinter( std::ostream& os )
        {
            return FramePrinter( os )
                .setAlignment( AlignmentMode::NONE )
                .showTypeInfo( false );
        }

        FramePrinter
        alignedPrinter( std::ostream& os )
        {
            return FramePrinter( os ).setAlignment( AlignmentMode::SEPARATOR );
        }

        FramePrinter
        columnarPrinter( std::ostream& os )
        {
            return FramePrinter( os ).setAlignment( AlignmentMode::COLUMNS );
        }

        FramePrinter
        jsonPrinter( std::ostream& os )
        {
            return FramePrinter( os ).setOutputFormat( OutputFormat::JSON );
        }

        FramePrinter
        walkingPrinter( std::ostream& os, int depth )
        {
            return FramePrinter( os )
                .setWalkObjects( true )
                .setWalkContainers( true )
                .setWalkDepth( depth );
        }

        FramePrinter
        fullWalkPrinter( std::ostream& os )
        {
            return FramePrinter( os )
                .setWalkObjects( true )
                .setWalkContainers( true )
                .setWalkDepth( 0 ); // 0 = unlimited depth
        }

        FramePrinter
        shallowPrinter( std::ostream& os )
        {
            return FramePrinter( os )
                .setWalkObjects( false )
                .setWalkContainers( false )
                .setWalkDepth( 0 );
        }

    } // namespace Debug
} // namespace FrameCPP

#endif /* !defined( SWIGIMPORTED ) */
