#!/usr/bin/perl -w
#----------------------------------------------------------------------
#
# copyright (C) Decaux Nicolas Aka 'GawiNDX'
# contributor: Nicolas Decaux <decauxnico@gmail.com>
#
# 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
#----------------------------------------------------------------------
    package esmith;

    use esmith::db;
    use esmith::config;
    use esmith::ConfigDB;
    use LWP::Simple;
    use LWP::UserAgent;
    use HTML::LinkExtor;
    use URI::URL;
    use Switch;
    use File::Basename;
    use File::Path;
	use List::Util 'first';

	#On verifie quelle action doit etre effectuee
	switch ($ARGV[0]){
		case('update') 			{&update_mirror}
		case('delete-obsolete')		{&delete_obsolete;}
	}
	exit(1);

sub update_mirror
{
    my $mozus_db = esmith::ConfigDB->open('Mozus');
    my $mozusstatus = $mozus_db->get('Mozus')->prop('status');
    exit(0) unless ($mozusstatus || 'disabled') eq 'enabled';
    my $apps = $mozus_db->get('Mozus');
    my $thunder = $apps->prop('thunderbird') || 'disabled';
    my $firefox = $apps->prop('firefox') || 'disabled';
    my $mirror = $apps->prop('mirrorlink') || 'http://download-origin.cdn.mozilla.net';
    my $mirrordir = $apps->prop('mirrordir') || '/opt/mozilla-updates/mirror';
    my $mozver = $apps->prop('version') || '10';
    my @version = split('@',$mozver);
    my $mozlang = $apps->prop('locale') || 'fr';
    my @lang = split('@',$mozlang);
    my $mozpform = $apps->prop('platform') || 'win32';
    my @platform = split('@',$mozpform);
    my @syncapps = ();
    my @newversion = ();

    push(@syncapps,'thunderbird') if ($thunder eq 'enabled');
    push(@syncapps,'firefox') if ($firefox eq 'enabled');

	@listsync = ([],[],[]);	
	foreach my $syncapp (@syncapps) {
		$html = "$mirror/pub/$syncapp/releases";
		$url = $html;
		$ua = LWP::UserAgent->new;
		# Set up a callback that collect image links
		@links=();
		sub callback {
			my($tag, %attr) = @_;
			return if $tag ne 'a';
			push(@links, values %attr);
		}
		# Make the parser.  Unfortunately, we don't know the base yet
		# (it might be diffent from $url)
		$p = HTML::LinkExtor->new(\&callback);

		# Request document and parse it as it arrives
		$res = $ua->request(HTTP::Request->new(GET => $url), sub {$p->parse($_[0])});
		# Expand all image URLs to absolute ones
		my $base = $res->base;
		@links = map { $_ = url($_, $base)->abs; } @links;

		foreach $link (@links){
			my $testver =  substr $link, ( index($link, 'releases/') + 9 ) , 2 ;
			if ( $link =~ /esr/  and $link !~ /latest/ ){
				if ( grep( /^$testver$/, @version )) { 
					foreach $pform (@platform){
						foreach $language (@lang) {
							$html="$link"."update/"."$pform/$language/";
							$ua = LWP::UserAgent->new;
							@linkapps = ();
							sub callbacknd {
								my($tag, %attr) = @_;
								return if $tag ne 'a';
								push(@linkapps, values %attr);
							}
							$p = HTML::LinkExtor->new(\&callbacknd);
							$res = $ua->request(HTTP::Request->new(GET => $html), sub {$p->parse($_[0])});
							my $base = $res->base;
							@linkapps = map { $_ = url($_, $base)->abs; } @linkapps;
							foreach $linkapp (@linkapps){			
								if ( $linkapp =~ /.mar/ and $linkapp !~ /asc/ ){
									my $destdir = substr $linkapp, ( index($linkapp, 'releases/') + 9);
									$destdir = "$mirrordir/$syncapp/$destdir";
									my ($filename, $directories) = fileparse($destdir);
									my @dir_dest = split('/', $directories);
									my $newver = substr( $dir_dest[5],0, -3 );
									@newversion = split('\.', $newver );
									push(@newversion, "0") if ((scalar @newversion) < 3 );
									$newversion[2] = "0$newversion[2]" if ($newversion[2] < 10);
									$newver = join('.',@newversion)."esr";
									if ( $syncapp eq 'thunderbird' ) {
										$dir_dest[4] = "Thunderbird";
									}elsif ( $syncapp eq 'firefox' ) {
										$dir_dest[4] = "Firefox";
									}
									$dir_dest[5] = $newver;
									switch ($pform){
										case('win32') 		{ $dir_dest[7] = 'WINNT_x86-msvc'; }
										case('mac')   		{ $dir_dest[7] = 'Darwin_x86-gcc3'; }
										case('linux-i686')		{ $dir_dest[7] = 'Linux_x86'; }
										case('linux-x86_64')		{ $dir_dest[7] = 'Linux_x86_64'; }
										else 				{ die; }
									}
									$directories = join("/",@dir_dest)."/";
									push(@{$listsync[0]},$linkapp);
									push(@{$listsync[1]},$filename);
									push(@{$listsync[2]},$directories);
								}
							}	
						}
					}
				}else{
					my $dispo_ver = $apps->prop('VersionDispo') || '10';
					my @add_version = split('@',$dispo_ver);
					if ( !grep( /^$testver$/, @add_version )) {
						push (@add_version, $testver);
						my $new_mozver= join('@',@add_version);
						$apps->set_prop('VersionDispo',$new_mozver);
					}
				}
			}
		}
	}
	foreach $row (0..@{$listsync[0]}-1)   {
		my $file = $listsync[1][$row];
		$file =~ s/%20/\ /g;
		my $link = $listsync[0][$row];
		my $directory = $listsync[2][$row];
		my $dirfile = "$directory$file";
		unless ( -e "$directory$file" ){
			unless( -d $directory ){
				mkpath($directory) or die;
			}
			my $status = getstore($link, $dirfile);
			die "Error $status on $url" unless is_success($status);
		}	
	}
	exit(1);
}

sub delete_obsolete
{
	my $mozus_db = esmith::ConfigDB->open('Mozus');
	my @locale = split('@', $mozus_db->get_prop('Mozus','locale'));
	my @platformsave = split('@',$mozus_db->get_prop('Mozus','platform'));
	my @listversion = split('@',$mozus_db->get_prop('Mozus','version'));
	my $ff_status = $mozus_db->get_prop('Mozus','firefox');
	my $tb_status = $mozus_db->get_prop('Mozus','thunderbird');
	my $mirrordir = $mozus_db->get_prop('Mozus','mirrordir') || "/opt/mozilla-updates/mirror";
	my @remove_dir;
	my @product;
	if (( $ff_status eq 'disabled') and ( -d "$mirrordir/Firefox") ) {
		push(@remove_dir, "$mirrordir/Firefox/");
	}else{
		push(@product, "Firefox");
	}
	if (( $tb_status eq 'disabled') and ( -d "$mirrordir/Thunderbird") ) {
		push(@remove_dir, "$mirrordir/Thunderbird/");
	}else{
		push(@product, "Thunderbird");
	}
	my %platform =	(	'win32'			=> 'WINNT_x86-msvc',
						'mac'			=> 'Darwin_x86-gcc3',
						'linux-i686'	=> 'Linux_x86-gcc3',
						'linux-x86_64'	=> 'Linux_x86_64-gcc3' );
	my @target_platform;
	foreach my $pform (@platformsave){
		push (@target_platform , $platform{$pform});
	}	
	foreach my $prod (@product){
		if ( -e "$mirrordir/$prod"){
			my @Directory = GetFilesList ("$mirrordir/$prod");
			foreach my $Dir  (@Directory) {
				my @array_Dir = split ( '/', $Dir);
				my $dudu = scalar(@array_Dir);
				if ( scalar(@array_Dir) >= 9 ){
					if ( ( (first { /$array_Dir[8]/ } @locale ) || '') eq '' ) {
						push (@remove_dir, "$Dir/");
						next;
					}
				}
				if ( scalar(@array_Dir) >= 8 ){
					if ( ( (first { /$array_Dir[7]/ } @target_platform ) || '') eq '' ) {
						push (@remove_dir, "$Dir/");
						next;
					}
				}
				if ( scalar(@array_Dir) >= 6 ){
					$array_Dir[5] =~s/\./,/g ;
					my @array_version = split(',',$array_Dir[5]);
					if ( ((first { /$array_version[0]/ } @listversion ) || '') eq '' ) {
						push (@remove_dir, "$Dir/");
						next;
					}
				}
			}
		}
	}
	foreach my $Dir (@remove_dir){
		rmtree($Dir,0,0);
	}
}

sub GetFilesList
{
        my $Path = $_[0];
        my $FileFound;
        my @FilesList=();

        # Lecture de la liste des fichiers
        opendir (my $FhRep, $Path)
                or die "Impossible d'ouvrir le repertoire $Path\n";
        my @Contenu = grep { !/^\.\.?$/ } readdir($FhRep);
        closedir ($FhRep);

        foreach my $FileFound (@Contenu) {
                if ( -d "$Path/$FileFound") {
					push ( @FilesList, "$Path/$FileFound" );
				# Boucle pour lancer la recherche en mode recursif
                        push (@FilesList, GetFilesList("$Path/$FileFound") );
                }

        }
        return @FilesList;
}