#! /usr/bin/perl -w

# vim:syntax=perl

use strict;

use lib '/usr/share/perl5';

use Locale::TextDomain qw/lire/;

use Lire::Logger;
use Lire::Config;
use Lire::Config::SpecParser;
use Lire::Error qw/ an_error_occured /;
use Lire::DlfSchema;
use Lire::ReportSpec;
use Lire::FilterSpec;
use Lire::ReportConfig;
use Lire::XMLSpecI18N;
use Lire::PluginManager;
use Getopt::Long;
use Lire::Utils qw/file_content/;

sub usage {
    lr_err( @_,
            __(
"Usage: lr_spec2pot [--cfgspecdir <dir>]*
                    [--reportsdir <dir>]*
                    [--filtersdir <dir>]*
                    [--pluginsdir <dir>]*
                    [--schemasdir <dir>]* <SPECS>+\n" ) );
}

sub setup_cfg_paths {
    my $specdirs = $_[0];

    # Clear the spec path
    foreach my $dir ( Lire::Config->config_spec_path() ) {
        Lire::Config->del_config_spec_path_dir( $dir );
    }
    foreach my $dir ( @$specdirs ) {
        Lire::Config->add_config_spec_path_dir( $dir );
    }
    Lire::Config->init();

    return;
}

sub setup_cfg_var {
    my ( $listname, $varname, $dirs ) = @_;

    return unless defined $dirs;

    my $path = Lire::Config->get_var( $listname );
    my $dir_spec = $path->spec()->get( $varname );

    # Clear the path
    $path->clear();

    # Adds the new dirs
    foreach my $dir ( @$dirs ) {
        $path->append( $dir_spec->instance( 'value' => $dir )  );
    }

    return;
}

sub setup_plugins {
    my ( $pluginsdirs ) = @_;

    return unless $pluginsdirs;

    foreach my $dir ( @$pluginsdirs ) {
        opendir my $dh, $dir
          or die( "opendir '$dir' failed: $!\n" );
        foreach my $basename ( readdir $dh ) {
            next unless $basename =~ /_init$/;
            eval file_content( "$dir/$basename" );
            die( "error loading '$dir/$basename': $@\n" )
              if $@;
        }
        closedir $dh;

        my $parser = new Lire::Config::SpecParser();
        $parser->{'_spec'} = Lire::Config->config_spec();
        $parser->merge_specifications_dir( "$dir" );
    }
}

sub load_templates {
    my $file = $_[0];

    my $parser = new Lire::Config::SpecParser();
    my $spec = $parser->parsefile( $file );
    my @templates = ();
    foreach my $comp ( $spec->components() ) {
        my $cfg = $comp->instance()->as_value();
        $cfg->filename( $file );
        push @templates, $cfg;
    }
    return @templates;
}

sub load_spec {
    my $spec = $_[0];

    if ( $spec =~ /^filter:(.*?):(.*)/ ) {
        return Lire::FilterSpec->load( $1, $2 );
    } elsif ( $spec =~ /^report:(.*?):(.*)/ ) {
        return Lire::ReportSpec->load( $1, $2 );
    } elsif ( $spec =~ /^report_cfg:(.+)/ ) {
        return load_templates( $1 );
    } elsif ( $spec =~ /^schema:(.*)/ ) {
        return Lire::DlfSchema::load_schema( $1 );
    } elsif ( $spec =~ /^config_spec:(.*)/ ) {
        my $file = $1;
        my $parser = new Lire::Config::SpecParser();
        $parser->merge_specification( $file );
        my $obj = $parser->configspec();
        $obj->xml_file( $file );
        return $obj;
    } else {
        die __( "specs are strings of the form schema:<id>, filter:<schema>:<id>, report:<schema>:<id>, config_spec:<file> or report_cfg:<file>\n" );
    }
}

my %opts = ();
my $success = GetOptions( \%opts, 'cfgspecdir=s@', 'reportsdir=s@',
                          'filtersdir=s@', 'schemasdir=s@',
                          'pluginsdir=s@' );

setup_cfg_paths( $opts{'cfgspecdir'} )
  if ( defined $opts{'cfgspecdir'} );

usage() unless $success;

usage( "missing one or more spec arguments\n" )
  unless @ARGV;

# Since this script is used from the source tree before any Lire installation
# exists, we cannot 'use' Lire::Program. Otherwise it will try to parse the
# not-yet installed configuration files.
require Lire::Program;

eval {
    setup_cfg_var( 'lr_schemas_path', 'schemas', $opts{'schemasdir'} );
    setup_cfg_var( 'lr_reports_path', 'reports', $opts{'reportsdir'} );
    setup_cfg_var( 'lr_filters_path', 'filters', $opts{'filtersdir'} );
    setup_plugins( $opts{'pluginsdir'} );
};
lr_err( an_error_occured( $@ ) ) if $@;

my @specs = ();
foreach my $spec ( @ARGV ) {
    eval {
        push @specs, load_spec( $spec );
    };
    lr_warn( __x( "Error loading spec '{spec}': {error}",
                  'spec' => $spec, 'error' => $@ ) )
      if $@;
}

eval {
    my $extractor = new Lire::XMLSpecI18N( @specs );
    $extractor->generate_catalog();
};
lr_err( an_error_occured( $@ ) ) if $@;

# Local Variables:
# mode: cperl
# End:

__END__

=pod

=head1 NAME

lr_spec2pot - extracts strings for L10N from Lire XML specifications

=head1 SYNOPSIS 

FIXME

=head1 DESCRIPTION

FIXME


=head1 VERSION

$Id: lr_spec2pot.in,v 1.7 2006/07/23 13:16:33 vanbaal Exp $

=head1 AUTHORS

Francis J. Lacoste <flacoste@logreport.org>
Wolfgang Sourdeau <wolfgang@logreport.org>

=head1 COPYRIGHT

Copyright (C) 2004 Stichting LogReport Foundation LogReport@LogReport.org

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 (see COPYING); if not, check with
http://www.gnu.org/copyleft/gpl.html.

=cut


