#!%PERL%
# Copyright (c) vhffs project and its contributors
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without 
# modification, are permitted provided that the following conditions 
# are met:
#
# 1. Redistributions of source code must retain the above copyright 
#   notice, this list of conditions and the following disclaimer.
#2. Redistributions in binary form must reproduce the above copyright
#   notice, this list of conditions and the following disclaimer in 
#   the documentation and/or other materials provided with the 
#   distribution.
#3. Neither the name of vhffs nor the names of its contributors 
#   may be used to endorse or promote products derived from this 
#   software without specific prior written permission.
#
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
#"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
#LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
#FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
#COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
#INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
#BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
#LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
#CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
# POSSIBILITY OF SUCH DAMAGE.

package Vhffs::Robots::Svn;

use strict;
use utf8;

use Vhffs::Services::Svn;
use Vhffs::Constants;
use Vhffs::Functions;

sub change_conf
{
	my $svn	= shift;
	return -1 unless defined $svn;

	my $file = $svn->get_dir.'/conf/svnserve.conf';
	return -1 unless -f $file;

	my @lines;
	open( FILE , $file );
	while( <FILE> )
	{
		push( @lines , $_ );
	}
	close( FILE );


	open( FILE , '>'.$file );
	foreach my $line ( @lines )
	{
		if( $line =~ /.*anon\-access.*/ )
		{
			if( $svn->is_public == 1 )
			{
				$line = 'anon-access = read'."\n";
			}
			else
			{
				$line = 'anon-access = none'."\n";
			}
		}
		if( $line =~ /.*\[general\].*/ )
		{
			$line = '[general]'."\n";
		}
		print FILE $line;
	}
	close( FILE );


	# -- commit mail
	my $svnconf = $svn->{'main'}->get_config->get_service('svn');
	my $mailfrom = $svnconf->{'notify_from'};
	my $mailto = $svn->{ml_name};
	if( defined $mailfrom && defined $mailto )  {

		my @lines;

		# read template file
		open( POSTCOMMIT , '%VHFFS_BOTS_DIR%/misc/svn_post-commit.pl' );
		while( <POSTCOMMIT> )   {
			push( @lines , $_ );
		}
		close( POSTCOMMIT );

		# write hook
		unlink ( $svn->get_dir().'/hooks/post-commit' );
		open ( POSTCOMMIT , '>'.$svn->get_dir().'/hooks/post-commit' );
		foreach my $line ( @lines )  {

			# remplace some parameters
			$line =~ s/%MAILNOTIFYFROM%/$mailfrom/g;
			$line =~ s/%MAILNOTIFYTO%/$mailto/g;

			print POSTCOMMIT $line;
		}
		close ( POSTCOMMIT );
		chmod 0755 , $svn->get_dir().'/hooks/post-commit';
	}
	
	$svn->add_history( 'Changed configuration of SVN repository' );

	return 0;
}


sub create_repo
{
	my $svn = shift;
	return -1 unless defined $svn;
	return -1 if $svn->get_status != Vhffs::Constants::WAITING_FOR_CREATION;

	my $dir = $svn->get_dir;

	if( -e $dir ) {
		$svn->set_status( Vhffs::Constants::CREATING_ERROR );
		$svn->commit();
		$svn->add_history('Error, directory of this svn repository already exists! Administrators must fix the problem.');
		return -1;
	}

	Vhffs::Functions::create_dir( $dir );
	Vhffs::Functions::chmod_recur( $dir , 0664 , 02775 );
	Vhffs::Functions::change_owner_recur( $dir , $svn->get_owner_uid , $svn->get_owner_gid );
	$svn->add_history('Ok, robots find the empty directory and will create svn repository');

	system('svnadmin create --fs-type fsfs '.$dir);

	unless( -f $dir.'/format' ) {
		$svn->set_status( Vhffs::Constants::CREATING_ERROR );
		$svn->commit();
		$svn->add_history('Error, nothing was created after calling the svnadmin binary, something is wrong.');
		return -1;
	}	

	Vhffs::Functions::chmod_recur( $dir , 0664 , 02775 );
	Vhffs::Functions::change_owner_recur( $dir , $svn->get_owner_uid , $svn->get_owner_gid );

	# './hooks' directory must be owned by root to prevent abuse of servers
	Vhffs::Functions::chmod_recur( $dir.'/hooks' , 0644 , 0755 );
	Vhffs::Functions::change_owner_recur( $dir.'/hooks' , 0 , 0 );
	
	change_conf( $svn );

	$svn->add_history('The Robots created the subversion repository');
	$svn->set_status( Vhffs::Constants::ACTIVATED );
	$svn->commit();

	return 0;
}




sub delete_repo
{
	use File::Path;
	use File::Basename;
	my $svn = shift;
	return -1 unless defined $svn;

	my $dir = $svn->get_dir;
	File::Path::rmtree($dir);
	my $group_dir = dirname($dir);
	rmdir $group_dir;
	
	return 0;
}


1;
