############################################################################
##      Copyright (C) 2005 Subredu Manuel  <diablo@iasi.roedu.net>.        #
##                                                                         #
## This program is free software; you can redistribute it and/or modify    #
## it under the terms of the GNU General Public License v2 as published by #
## the Free Software Foundation.                                           #
##                                                                         #
## 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.                                                      #
############################################################################

package RoPkg::Simba::Plugin::GenRsync;

use strict;
use warnings;

use RoPkg::Exceptions;
use RoPkg::Rsync::ConfFile;

use Scalar::Util   qw(blessed);
use English        qw(-no_match_vars);
use Number::Format qw(:subs :vars);

use vars qw($VERSION);

$VERSION='0.1.1';

sub new {
  my ($class, %opt) = @_;
  my $self;

  $self = bless { %opt }, $class;

  $self->{cf} = new RoPkg::Rsync::ConfFile();

  return $self;
}

sub _enabled {
  my ($self, $cfg) = @_;

  #if enabled found
  if ( $cfg->{enabled} ) {

    #return 1 if the value is yes (case insensitive)
    return 1 if ( $cfg->{enabled} =~ m{^yes$}xmi );

    #else, return 0
    return 0;
  }

  #if no enabled was found, assume yes
  return 1;
}

sub _load_config {
  my ($self, $cfg) = @_;
  
  foreach(keys %{$cfg->{plugins}}) {
    next if ( $_ ne 'rsync' );

    $self->{cfg} = $cfg->{plugins}->{$_};
  }

  return 1;
}

sub createRsyncConfig {
  my ($self, $cfg, $mirrors) = @_;
  my $htmls;
 
  if ( !blessed($self) ) {
    OutsideClass->throw('Called outside class instance');
  }

  #do nothing if no configuration items are found
  return 0 if ( !$cfg->{plugins}->{rsync} );

  #do nothing if plugin is disabled
  return 0 if ( !$self->_enabled($cfg->{plugins}->{rsync}) );

  #nothing to do if no mirrors are given
  return 0 if ((scalar @{ $mirrors }) <= 0 );

  $self->_load_config($cfg);
  $self->_check_files();
  
  return $self->_gen_rsyncd_config($mirrors);
}

sub _check_files {
  my ($self) = @_;
  my ($path, $fh);

  if ( $self->{cfg}->{source} ) {
    $path = $self->{cfg}->{source};

    if ( ! -f $path ) {
      File->throw($path . ' is not a file' . $RS);
    }

    open($fh, '<', $path)
      or File::Open->throw('Could not open ' . $path . $RS . $ERRNO . $RS);
    close($fh);
  }

  $path = $self->{cfg}->{outfile};
  open($fh, '>', $path)
    or File::Create->throw('Could not create ' . $path . $RS . $ERRNO . $RS);
  close($fh);

  return 1;
}

sub _gen_rsyncd_config {
  my ($self, $mirrors) = @_;
  my ($cf, $cfg);

  $cf  = $self->{cf};
  $cfg = $self->{cfg};

  if ( $cfg->{source} ) {
    $cf->Parse($cfg->{source});
  }
  else {
    $self->_init_rsyncd_cf($cf);
  }

  foreach(@{ $mirrors }) {
    my $node;
    my $mirror = $_;

    $node = new RoPkg::Rsync::Node(node_name => $mirror->Name);
    $node->AddParam('path', $mirror->LocalDir);
    $node->AddParam('comment',
             sprintf("%s (%sB)",
               $mirror->Name,
               $self->_get_nice_number($mirror->Size),
             ),
           );
    $node->AddBlank(q{});

    $cf->AddNode($node);
  }

  return $cf->Write($cfg->{outfile});
}

sub _get_nice_number {
  my ($self, $number) = @_;

  $KILO_SUFFIX  = q{ K};
  $MEGA_SUFFIX  = q{ M};
  $GIGA_SUFFIX  = q{ G};
  $DECIMAL_FILL = 0;
  $DECIMAL_DIGITS = 0;

  return Number::Format::format_bytes($number);
}


sub _init_rsyncd_cf {
  my ($self, $cf) = @_;
  my $cfg;

  $cfg = $self->{cfg};

  if ( $cfg->{defaults} ) {
    $cf->AddComment('# Generated by Simba');
    foreach(keys(%{ $cfg->{defaults}})) {
      $cf->AddParam($_, $cfg->{defaults}->{$_});
    }
    $cf->AddBlank(q{});
  }
  else {
    $cf->AddComment('# Generated by Simba');
    $cf->AddBlank(q{});
    $cf->AddParam('uid','nobody');
    $cf->AddParam('gid','nobody');
    $cf->AddParam('use chroot','yes');
  }

  return $cf;
}


1;

__END__

=head1 NAME

RoPkg::Simba::Plugin::GenRsync

=head1 DESCRIPTION

GenRsync is a rsync configuration generator plugin
for Simba. GenRsync allows you to create 
rsync configuration files on the fly using
mirror information from the database.

=head1 PREREQUISITES

GenRsync needs the following perl modules:

=over 3

=item *) RoPkg::Rsync

=item *) Scalar::Util

=item *) Number::Format

=back

=head1 METHODS

=head2 genRsyncConfig($cfg, @mirrors)

Generate rsync configuration files. The $cfg param 
is a hash reference to the simba configuration file.
This methods is called by Simba.

=head1 CONFIGURATION

All configuration documentation is available on the website
(http://simba.packages.ro).

=head1 SEE ALSO

L<RoPkg::Simba> L<RoPkg::Exceptions>

=head1 AUTHOR

Subredu Manuel <diablo@iasi.roedu.net>

=head1 LICENSE

Copyright (C) 2005 Subredu Manuel.  All Rights Reserved.
This module is free software; you can redistribute it 
and/or modify it under the same terms as Perl itself.
The LICENSE file contains the full text of the license.

=cut
