#!/usr/bin/perl
use strict;
use warnings;
#use Pod::Help qw(-h --help);
use Pod::Usage;
use Getopt::Long;

    ## Parse options
    my %opt;
    GetOptions(\%opt, "help|?", "man", "flag1", "version")  ||  pod2usage(2);
    pod2usage(1)  if ($opt{help});
    if ($opt{version}){
        print "Version 3\n";
	exit;
    };
    pod2usage(-exitval => 0, -verbose => 2)  if ($opt{man});

    ## Check for too many filenames
    pod2usage("$0: Too many files given.\n")  if (@ARGV > 2);


#print " $ARGV[0] $ARGV[1]\n";

my $ac=scalar @ARGV;
if ($ac<2){
    print STDERR "Cantidad insuficiente de argumentos\n";
    exit;
}

=pod
 
=head1 NAME

    sample - Using GetOpt::Long and Pod::Usage

=head1 SYNOPSIS

    sample [options] [file ...]

     Options:
       -help            brief help message
       -man             full documentation

=head1 OPTIONS

=over 4

=item B<-help>

    Print a brief help message and exits.

=item B<-man>

    Prints the manual page and exits.

=back

=head1 DESCRIPTION

    B<This program> will read the given input file(s) and do something
    useful with the contents thereof.
 
=cut



# traduce los nombres de paquete de debian a otras distros o a perl u otro
#usa archivo packs.data

# si pedimos un paquete de perl y no lo encuentra obviamente, hace un abusqueda inversa, deduce su paquete debian si esta y lo encuentra en la distro que sea

#perl ./packinstall.pl DEBIAN Data::Dumper0  HTTP::DAV  fortran gcc nano  REPO-ppa:ubuntu-toolchain-r/test gfortran-6 Data::Dumper0  Data::Dumper Data::Dumperio nnju mc

#use Data::Dumper; #solo necesario para desarrollar
# es el que instala modulos, no debe usar ninguno !!!!!
#use List::MoreUtils qw(uniq);
#use Time::localtime;
#use File::stat;
# --force-yes replaced by  --allow-downgrades --allow-remove-essential --allow-change-held-packages
#funciona en windows 95 pero no hay home ni user, en adelante 
#foreach $key (keys(%ENV)) {
#    printf("%-10.10s: $ENV{$key}\n", $key);
#}
# en otros windows HOMEPATH USERNAME WINDIR
#PATH TMP TEMP CMDLINE WINBOOTDIR

# system no interfiere con los impresos de los comandos las backtics los capturan
    
#poner abrearchivo en modulo, pero se complica instalacion



my $comi=1;

my $endistro=0;
my  @ldist=("SUSE","GENTOO","PERL","DEBIAN","MANDRIVA","REDHAT","UBUNTU","LATEX","UTUTO","ARCH"); #ni ARCH ni LATEX estra instrumentados en distro.sh
foreach my $JJ (@ldist){
   print "$JJ   $ARGV[0]\n";
   if ($ARGV[0] eq $JJ){
       print "OK\n";
       $endistro=1;
       }
   }



if (not $endistro){
    my $dis=distro();
    if (not $dis){
	print "ERROR: No reconozco distro $dis";
	exit(1);
    }else{
        $comi=0;

    }
    #print "MMM $ARGV[0]\n";
}
#si no es alguna de esta ver llamarla X y ver que se hace

# ver script para detectar instalador, simple si existen apt-get urpmi etc, otra contando paquetes

######################################################################3
my $pac;
my $pacu;
my $pacuni;
my $repos;
my $dosp;

foreach ($comi .. $ac-1){
    my $an=$ARGV[$_];
    if ($ARGV[$_]=~s/::/--/g){
	$dosp->{$ARGV[$_]}=$an;
          }	
    #OYE si tiene dos puntos es perl , aunque puede no tenerlo
    
    if ($ARGV[$_]=~s/REPO-//){
	if (not defined $repos->{$ARGV[0]}){$repos->{$ARGV[0]}=[]};
	     $repos->{$ARGV[0]}=[@{$repos->{$ARGV[0]}},$ARGV[$_]];
    }else{
    
        my ($DISTRO,$PACK)=busca($ARGV[$_],$ARGV[0]);
      
        print "  BUSCA $ARGV[$_]:$DISTRO,$PACK\n";
	if ($PACK){
           if (not defined $pac->{$DISTRO}){$pac->{$DISTRO}=[]}
           $pac->{$DISTRO}=[@{$pac->{$DISTRO}},$PACK];
	}
    }

}

   foreach my $dis (sort keys %{$pac})	{
       my $paque='';
       #print "lista @{$pac->{$dis}}\n";
	foreach  (uniq (sort  @{$pac->{$dis}}))	{
	    $paque.=" ".$_;
	    #print "NNN $_\n";
	      }    
       print "$dis: $paque ;";
       $pacu->{$dis}=[uniq (sort  @{$pac->{$dis}})];
        }
print "\n";

#print Dumper $pacu;
######################################################################
#print Dumper $pac;

#   si esta instalado devuelve: install ok installed
#   si no: install ok not-installed
#   si no existe el paquete: nada
my $deboinstalar=0;
   foreach my $dis (sort keys %{$pacu})	{
       if ($dis eq "DEBIAN" or $dis eq "UBUNTU"){
	foreach  my $PACK ( @{$pacu->{$dis}})	{
	   #my	$OKI=`dpkg -s "$PACK"  2>&1 |grep "dpkg-query: package" |grep " is not installed"`;
	   my $OKI=`dpkg-query -W -f='\${Status}' "$PACK" 2>/dev/null | grep -v not`;

           #print "MMM $PACK $OKI\n";
           if (not $OKI){ 
	     print"  Debian $PACK NO esta instalado\n"; 
	

	     
	     # sudo -n DEBIAN_FRONTEND=noninteractive apt-get --no-upgrade -y install $PACK
	     $pacuni->{$dis}->{$PACK}=1;   #usar array para respetar orden!!!!
	     $deboinstalar=1;
	  }else{ 
	     print "  Debian $PACK SI esta instalado\n";        
             }
          }	
       }elsif($dis eq "SUSE" ){
	   	foreach  my $PACK ( @{$pacu->{$dis}})	{
		 
		}
       }elsif($dis eq "REDHAT"){
	   	foreach  my $PACK ( @{$pacu->{$dis}})	{

		}
       }elsif ($dis eq "MANDRIVA"){
	   	foreach  my $PACK ( @{$pacu->{$dis}})	{

		}
       }elsif($dis eq "PERL"){
	   foreach  my $PACK ( @{$pacu->{$dis}})	{
	     
	       $PACK=~s/--/::/g;
	       if (try_load($PACK)) {
	  	      print "  Perl $PACK SI esta instalado \n";
                  }else{
		      print "  Perl $PACK NO instalado\n";
		      $pacuni->{$dis}->{$PACK}=1;
		       $deboinstalar=1;
	             }
		  #`cpanm --sudo  $PACK` ;
		}
       }elsif($dis  eq "GENTOO" or $dis eq "UTUTO"){
	   	foreach  my $PACK ( @{$pacu->{$dis}})	{

		}
	}



}

# hay que instalar repositorios
#print Dumper $repos;
my $reposni;
  foreach my $dis (sort keys %{$repos}){
    foreach  my $REPO ( @{$repos->{$dis}})	{
       my $test=`ls /etc/apt/sources.list.d/ubuntu-toolchain-r-ubuntu-test* | wc -l`;
       if ($test == 0) {
      	  if (not defined $reposni->{$dis}){$reposni->{$dis}=[]};
	  $reposni->{$dis}=[ @{$reposni->{$dis}},$REPO]; 
          $deboinstalar=1;
	}
    }}

  #print Dumper $reposni;
  my $OKSUDO='';



  # es necesario instalar sudo?
 
 
   if ($ARGV[0] eq "DEBIAN" or $ARGV[0] eq "UBUNTU"){   # en realidad ubuntu siempre tiene sudo
       $OKSUDO=`dpkg-query -W -f='\${Status}' sudo | grep -v deinstall`;
       #print "\nDEBO $deboinstalar - $OKSUDO - $ARGV[0]\n";
       if (not $OKSUDO){
	   print "INFO: Debo instalar sudo\n";
          $deboinstalar=1;
          } 
       }
 
  
#print "DEBO $deboinstalar - $OKSUDO\n";


# poner algo que registre cuando si hizo, si se hizo en 4 horas , no hacer




foreach my $dis (sort keys %{$reposni}){
    foreach  my $PACK ( @{$reposni->{$dis}})	{
	if ($dis eq "DEBIAN" or $dis eq "UBUNTU" and $deboinstalar){
	    print "sudo repository $PACK\n";
	    system("sudo add-apt-repository -y $PACK;");
	    }
	  }
	}
my $soloperl=1;
    foreach my $dis (sort keys %{$pacuni}){
	if ($dis ne "PERL"){
	    $soloperl=0;
	   }
	}

if ($deboinstalar and not $soloperl){



    my $time=0;
    if (-e "/tmp/update.time"){
	        #print "mm\n";
	        my $dat  = (stat("/tmp/update.time"))[9];
		$time=$dat;
    }


    my $seconds=time()-$time;
    #print "SECONDS $seconds $time\n ";
    if ($seconds/3600>12){
    
    print "Hay cosas para instalar debo hacer update\n";
    # si solo son perl no

     if (not $OKSUDO){
	        print "Ahora es posible que le pida la contraseña de root (su), espera a que se la pida. \n" ;
   	        system('su - -c "apt-get update"');
		}else {
	        print  "Ahora es posible que le pida la contraseña de usuario (sudo), espere a que se la pida. \n"; 
		system("sudo apt-get update") ;
	      }
             system("touch /tmp/update.time");
    }
}
      my @usuario=getpwuid($<);
      my $USERNAME=$usuario[7];
if ($deboinstalar and not $OKSUDO){

    print  "INSTALAR SUDO \n";
	 print "Ahora puede pedirle la contraseña de root para su, mas adelante la de usuario para sudo, espere a que se la pida.\n" ;
	 system('su - -c "apt-get   --allow-downgrades --allow-remove-essential --allow-change-held-packages --yes install sudo && adduser $USERNAME sudo"') ; 

}

#	if test x"$$OKI" = x ; then \
#	 echo "INSTALAR SUDO $$OKI"; \
#	 echo "ahora le pedira la contraseña de root, mas adelante la de usuario para sudo" ;\
#	 su - -c "apt-get  --force-yes --yes install sudo && adduser $(USERNAME) sudo" ; \
#	 exit ;\
#	fi;

#		print Dumper $pacuni;



if ($deboinstalar){
  foreach my $dis (sort keys %{$pacuni})	{
      my $fortran6=0;
      if($dis eq "DEBIAN" or $dis eq "UBUNTU"  ){
	  my $lp='';
	  foreach  my $PACK (sort  keys %{$pacuni->{$dis}})	{
	      if ($PACK eq 'fortan6'){
                  $fortran6=1;
	      }
		     $lp.= " ".$PACK;
		}
	  if ($lp){

     #export DEBIAN_FRONTEND=noninteractive ; sudo apt-get install $PACK; echo "";

           #usar noninteractive para postifix por ejemplo luego hay que reconfigurar
	   #sudo dpkg-reconfigure postfix
	     #debconf-set-selections.
#sudo debconf-set-selections <<< ‘mysql-server-<version> mysql-server/root_password password your_password’
#sudo debconf-set-selections <<< ‘mysql-server-<version> mysql-server/root_password_again password your_password’
#sudo apt-get -y install mysql-server
	      
	      system("sudo  DEBIAN_FRONTEND=noninteractive apt-get   --allow-downgrades --allow-remove-essential --allow-change-held-packages --yes install ".$lp);
              if ($fortran6){
                    fortran6(); 
	      }
	      
	      }
		
        }elsif($dis eq "SUSE" ){
	   	foreach  my $PACK ( sort  keys %{$pacuni->{$dis}})	{
		system("sudo zypper in $PACK");
		}
       }elsif($dis eq "REDHAT"){
	   	foreach  my $PACK ( sort  keys %{$pacuni->{$dis}})	{
	    system("sudo -n yum install $PACK");
		}
       }elsif ($dis eq "MANDRIVA"){
	   	foreach  my $PACK ( sort  keys %{$pacuni->{$dis}})	{
		   system("sudo -n urpmi       $PACK");
		}
       }elsif($dis eq "PERL"){
	   foreach  my $PACK ( sort  keys %{$pacuni->{$dis}})	{
	       
	       print "Instalara PAQ PERL $PACK\n";
        	    system("mkdir -p  ~/.cpanm;");
                    if (-d "~/.cpanm"){                               # todo esto porque www-data no puede escribir en su home
                       }else{     
			system("sudo mkdir -p ~/.cpanm;");                    # chown ~/.cpanm")
			my $ln=getpwuid($<);
			system ("sudo chown $ln:$ln  ~/.cpanm");
		    }
		    system("sudo cpanm --sudo  $PACK");
		  
		}
       }elsif($dis  eq "GENTOO" or $dis eq "UTUTO"){
	   	foreach  my $PACK ( sort  keys %{$pacuni->{$dis}})	{
		    system("sudo -n emerge  $PACK");
		}
       }
}
}
exit;
##################################################################
sub try_load {
  my $mod = shift;

  eval("use $mod");

  if ($@) {
    #print "\$@ = $@\n";
    return(0);
  } else {
    return(1);
  }
}

##########################################################3

sub abrearchivo{    
    my ($archivo,$tipoarchivo)=@_;
    my @usuario=getpwuid($<);

    # primero desarrollo, luego usuario, luego local, luego paquete

    # lo ideal es buscar donde esta este programa instalado y actuar en consecuencia!!!!, pero no es obvio saber donde esta instalado un programa perl que esta ejecutandose, se aceptan sugerencias
    # en linux cuando se lo corre como packinstall.pl da en $0 el path completo, si se lo llama como perl bin/packinstall.pl da bin/packinstall.pl
    #revisar
    
    my @filename;
    if ($tipoarchivo eq 'dato'){
      @filename=("../data/","$usuario[7]/.summapack/data/", "/usr/local/share/summapack/data/","/usr/share/summapack/data/");
    }
    #ineficiente la mayoria de las veces pero lo logico
    
    my $fh;
    my $tok=0;
    my @rfn=();
    foreach(@filename){
	$_.="packs.data";
	#print "DIR $_\n";
	@rfn=(@rfn,$_);
	if (-e $_){        
	 my $ok=open($fh, '<:encoding(UTF-8)', $_);
	 if ($ok){
	    $tok=1;
	    last;            
	    }
          }
    }
    if (not $tok){
	die "No pude abrir ninguno de los siguientes archivos: @rfn\n"; #!
    }
return $fh;
}
############################################################
sub uniq {
    my %seen;
    grep !$seen{$_}++, @_;
}
#########################################################
sub busca{
    # en cada paquete lee el archivo, ................. cambiar
    my ($pp,$dd)=@_;

    my $fh=abrearchivo('packs.data','dato');

    my $hdistro;

    my $perldistro;
    
    my $hperl='';
    my $tinfo;
while (my $row = <$fh>) {
     chomp $row;
    
     ($row)=split(/#/,$row);
     if (not $row){ next;}
     if ($row=~/^\s/){ next;}
     my ($idx,$distro,$pack)=split(/:/,$row);
       if ($idx){
     $idx=~s/^\s+//;
     $idx=~s/\s+$//;
       }else{
	   $idx='';
       }
       if ($distro){
           $distro=~s/^\s+//;
           $distro=~s/\s+$//;
       }else{
	   $distro='DEBIAN';
       }
     if ($pack){
       $pack=~s/^\s+//;
       $pack=~s/\s+$//;
     }else{
	 if ($distro eq "DEBIAN"){
	     $pack=$idx;
	 }else{
	     $pack='';
	 }
       }
     if ($idx){
	 $tinfo->{"DEBIAN"}->{$idx}=$idx;
	 if ($distro and $distro ne "PERL"){
	     $tinfo->{$distro}->{$idx}=$pack;
	 }
     }
     #     print "FILE: $idx,$distro,$pack\n";
     
     #if (not $idx and $pack){$idx=$pack;} # por si acaso alguien usa el nombre que un paquete tiene en esa "distro", por ej, perl
     #if (not $distro){$distro='DEBIAN';} # por si alguien pone paquetes sin distro, que serian paquetes debian, igual no se usa para nada

    
     if ($idx eq $pp){
         
	 if ($distro eq $dd){
	     #print " distro eq dd\n";
	     return ($dd,$pack);                     
	 }elsif($dd eq "DEBIAN") {
	     #print " dd es DEBIAN\n";
	     return ("DEBIAN",$idx);                     
	 }
	 #print "hdistro $distro $pack";
	 $hdistro->{$distro}=$pack;
     }
     if ($distro eq "PERL" and not $idx and $pack){
         $perldistro->{$pack}=1;
     }

     #  print "PERL >$pp<- >$pack< - >$distro< - >$idx<    \n";
     if ($pack and ($pack eq $pp)  and ($distro eq "PERL") and $idx){
         #print "ENCONTRO PERL Y SU NOMBRE DEBIAN $pack -> $idx\n";
	 $hperl=$idx;
	 
     }
     
}
    
    close ($fh);

    #print "BEQUI\n";

    #print Dumper $perldistro;
    #print "PERL\n";
    #print Dumper $perldistro;
    # si no hay otra, pero si perl, usar PERL
 
   my $res=$perldistro->{$pp};
   if ($res){
            return ("PERL",$pp);
	    }


   my $dis;
   ($dis,$res)=equival($dd,$hdistro,$pp); # salvo perl devuelve la misma distroque pidio
   if ($res){
      #print "EQUIVAL $res\n";
      return ($dis,$res);
    }

    
    #oops el paquete pedido es perl!
 # y si el paquete que pedimos es perl y sabemos cual es su paquete????  
    ###
    #print Dumper $tinfo;
    
    #print "BPERL  $hperl - $tinfo->{$dd}->{$hperl}\n";
    # paquetes perl que sabemos que tienen paquetes de distro
    if ($tinfo->{$dd}->{$hperl}){
      #print "PERL\n";
      return ($dd,$tinfo->{$dd}->{$hperl});
    }


   #if ($pack eq $pp and $distro eq "PERL" and $idx){
	# #SU DEBIAN ES $idx, entonces
	 #my ($DISTRO,$PACK)=busca($idx,$dd);
	 #return ($DISTRO,$PACK); 
    #}
    
   #### no buscamos si se metio el nombre de un paquete que es de otra distro
 
    #finalmente retorna lo que recibio, si no hay nada mejor
    #print "FIN\n";



#print "BULT $dd,$pp\n"; #incluyendo si es debian

    # si los puso por defecto para instalar pero tenian dos puntos .... son PERL!!!!
  if (exists $dosp->{$pp} and $dd ne "PERL"){
      return ("PERL",$pp);
	}
    
return ($dd,$pp);
}


#print Dumper $hdistro;

###############################################################################################################################

sub equival{
    my ($distro,$hdistro,$pack)=@_;

    my $eq;
    
 $eq->[0]=[qw/UBUNTU DEBIAN/];
 $eq->[1]=[qw/SUSE MANDRIVA REDHAT/];
 $eq->[2]=[qw/UTUTO GENTOO/];
 foreach my $i (0..2){
     foreach (@{$eq->[$i]}){
      #print "LL $_ - $distro\n";
      if ($distro eq $_){
	#print "ES 0\n";
	my @equiv=uniq ($distro,@{$eq->[$i]});
	#print "G @equiv\n";
	foreach my $j (1 .. scalar @equiv -1){
	    if ($equiv[$j] eq "DEBIAN"){
 		   #print EQUI DEBIAN $pack\n";
                   return ("DEBIAN",$pack);
                   }
	    my $res=$hdistro->{$equiv[$j]};
	     
	    if ($res){
		 #print "EQUI C $res -  $equiv[$j]\n";
                 return ($distro,$res);
	      }
	    }
 	next;    
        }
    }
 }


return ("","");
}


exit;


#use Config;
#print "OS $Config{osname}\n";
#print "KERNEL $Config{archname}\n";

 #if ($Config{osname} eq "linux") {
 #    my $pm='';

 #    do{	 
#	 my $eee=`whereis -b $_|awk '{print \$2}'|tr -d "\n"`;
 #          #type -p $_ | tr -d "\n"`;
#	 #print "FFF $_ - $eee\n";
 #        if (-x $eee) {
#             $pm = $_;
#	     #print "FFF $pm\n";
 #            last;
  #       }
 #    } for qw/apt-get yum emerge pacman urpmi zypper/; 

#     print "PM $pm\n";
#     if ($pm eq 'zypper'){
#        system('sudo zypper in gnuplot swig gsl gsl-devel libgsl0');
#     }elsif ($pm eq 'apt-get'){
#        #system('sudo apt-get install libgsl-dev gsl-bin libgsl2 swig gnuplot-x11');     
#     }
#}elsif($Config{osname} eq "MSWin32"){
#   print  Win32::GetOSVersion(), "\n";
#}

sub fortran6{
	if (-e "/usr/bin/gfortran-6"){
		system ("sudo rm /usr/bin/gfortran");
		system ("sudo ln -s /usr/bin/gfortran-6 /usr/bin/gfortran;");
	}
}


#if ($Config{osname} eq "linux") {
#     my $pm='';#
#
#}elsif($Config{osname} eq "MSWin32"){
#   print  Win32::GetOSVersion(), "\n";
#}



sub distro{
    # una distro puede tener varias de estas, contar paquetes manejado por cada una
    my $pm;
     do{         
         my $eee=`whereis -b $_|awk '{print \$2}'|tr -d "\n"`;
           #type -p $_ | tr -d "\n"`;
         #print "FFF $_ - $eee\n";
         if (-x $eee) {
             $pm = $_;
             #print "FFF $pm\n";
             last;
         }
     } for qw/apt-get yum emerge pacman urpmi zypper uget/; 

#    print "PM $pm\n";
     
     my $dist='';
     if ($pm){
     if ($pm eq "apt-get") {
	 $dist="DEBIAN";
     }elsif($pm eq "yum"){
	 $dist="REDHAT";
     }elsif($pm eq "pacman"){
    	 $dist="ARCH";
     }elsif($pm eq "emerge"){
    	 $dist="GENTOO";
     }elsif($pm eq "urpmi"){
    	 $dist="MANDRIVA";
     }elsif($pm eq "zypper"){
    	 $dist="SUSE";
     }elsif($pm eq "uget"){
     	 $dist="UTUTO";
     }
}	 
	 return $dist;
}


 
 #    if ($pm eq 'zypper'){
 #       system('sudo zypper in gnuplot swig gsl gsl-devel libgsl0');
 #    }elsif ($pm eq 'apt-get'){
 #       #system('sudo apt-get install libgsl-dev gsl-bin libgsl2 swig gnuplot-x11');     
 #    }



#	echo CPANM
#	if test -e  $(HOME)/.cpanm; then \
#	  sudo chmod -R 777 $(HOME)/.cpanm ; \
#	  echo "chmod -R 777 $(HOME)/.cpanm" ;\
#	fi ;
#	if ! test -e /usr/bin/cpanm ; then \
#	 if ! test -e /usr/local/bin/cpanm ; then \
#	     if ! test -e $(DOWN)/cpanm ; then \
#	           sudo  wget --no-check-certificate -O $(DOWN)/cpanm  http://cpanmin.us ;\
#	     fi ;\
 #            sudo install $(DOWN)/cpanm /usr/local/bin ;\
#	 fi; \
#	fi; 
#	cpanm --self-upgrade --sudo ;\
