#!/usr/bin/perl
#  Copyright (C) 2002  Stanislav Sinyagin
#
#  This program is free software; you can 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 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.

# $Id: configsnapshot.in,v 1.2 2005/01/25 13:46:27 ssinyagin Exp $
# Stanislav Sinyagin <ssinyagin@yahoo.com>

BEGIN { require '/usr/share/torrus/conf_defaults/torrus-config.pl'; }

use strict;
use Getopt::Long;

use Torrus::Log;
use Torrus::ConfigTree;
use Torrus::SiteConfig;
use Torrus::ConfigBuilder;

exit(1) if not Torrus::SiteConfig::verify();

my $tree;
my $help_needed;
our $verbose = 0;

our $outfile = 'snapshot.xml';

my $creator = "Torrus version 1.0.4\n" .
    "This file was generated by command:\n" .
    $0 . " \\\n";
foreach my $arg ( @ARGV )
{
    if( $arg =~ /^--/ )
    {
        $creator .= ' ' . $arg . ' ';
    }
    else
    {
        $creator .= "\'" . $arg . "\'\\\n";
    }
}
$creator .= "\nOn " . scalar(localtime(time));

my $ok = GetOptions('tree=s'   => \$tree,
                    'out=s'    => \$outfile,
                    'verbose'  => \$verbose,
                    'help'     => \$help_needed);

if( not $ok or not $tree or $help_needed or scalar(@ARGV) > 0 )
{
    print STDERR "Usage: $0 --tree=NAME [options...]\n",
    "Options:\n",
    "  --tree=NAME     tree name\n",
    "  --out=filename  output file [".$outfile."]\n",
    "  --verbose       print extra information\n",
    "  --help          this help message\n";
    exit 1;
}

if( $verbose )
{
    Torrus::Log::setLevel('verbose');
}

if( not Torrus::SiteConfig::treeExists( $tree ) )
{
    Error('Tree ' . $tree . ' does not exist');
    exit 1;
}


# This will ensure that all databases get closed correctly
$SIG{'TERM'} = sub
{
    Warn($0 . ' process terminated');
    exit 1;
};

$SIG{'INT'} = sub
{
    Warn($0 . ' process interrupted');
    exit 1;
};

my $config_tree = new Torrus::ConfigTree( -TreeName => $tree, -Wait => 1 );
if( not defined( $config_tree ) )
{
    exit 1;
}


my $cb = new Torrus::ConfigBuilder;

$cb->addCreatorInfo( $creator );

# We don't collect views, since they are in defaults.xml which is always
# included

collect_monitors( $config_tree, $cb );
collect_tokensets( $config_tree, $cb );
collect_definitions( $config_tree, $cb );
collect_subtrees( $config_tree, $cb, $config_tree->token('/') );

my $ok = $cb->toFile( $outfile );
if( $ok )
{
    Verbose('Wrote ' . $outfile);
}
else
{
    Error('Cannot write ' . $outfile . ': ' . $!);
}

exit($ok ? 0:1);

sub collect_monitors
{
    my $config_tree = shift;
    my $cb = shift;

    my $monitorsNode = $cb->startMonitors();

    foreach my $action ( $config_tree->getActionNames() )
    {
        my $params = $config_tree->getParams( $action );
        $cb->addMonitorAction( $monitorsNode, $action, $params );
    }

    foreach my $monitor ( $config_tree->getMonitorNames() )
    {
        my $params = $config_tree->getParams( $monitor );
        $cb->addMonitor( $monitorsNode, $monitor, $params );
    }
}

sub collect_tokensets
{
    my $config_tree = shift;
    my $cb = shift;

    my $tsetsNode = $cb->startTokensets();

    foreach my $tset ( $config_tree->getTsets() )
    {
        my $params = $config_tree->getParams( $tset );
        my $name = $tset;
        $name =~ s/^S//;
        $cb->addTokenset( $tsetsNode, $name, $params );
    }
}


sub collect_definitions
{
    my $config_tree = shift;
    my $cb = shift;

    my $definitionsNode = $cb->startDefinitions();

    foreach my $defName ( sort $config_tree->getDefinitionNames() )
    {
        my $value = $config_tree->getDefinition( $defName );
        $cb->addDefinition( $definitionsNode, $defName, $value );
    }
}

sub collect_subtrees
{
    my $config_tree = shift;
    my $cb = shift;
    my $token = shift;
    my $parentNode = shift;

    foreach my $ctoken ( $config_tree->getChildren( $token ) )
    {
        my $childName = $config_tree->nodeName( $config_tree->path($ctoken) );
        my $params = $config_tree->getParams( $ctoken, 1 );

        # Remove linebreaks
        while( my( $param, $value ) = each %{$params} )
        {
            $value =~ s/\s+/ /gm;
            $params->{$param} = $value;
        }

        if( $config_tree->isSubtree( $ctoken ) )
        {
            my $subtreeNode =
                $cb->addSubtree( $parentNode, $childName, $params );
            collect_subtrees( $config_tree, $cb, $ctoken, $subtreeNode );
        }
        elsif( $config_tree->isLeaf( $ctoken ) )
        {
            $cb->addLeaf( $parentNode, $childName, $params );
        }

        foreach my $aliasToken ( $config_tree->getAliases( $ctoken ) )
        {
            $cb->addAlias( $parentNode, $config_tree->path( $aliasToken ) );
        }
    }
}



# Local Variables:
# mode: perl
# indent-tabs-mode: nil
# perl-indent-level: 4
# End:
