#!/usr/bin/env perl
if ($0 =~ /([^(\/)]+)$/) {
    push (@INC, "$`lib/");
}
require "RSA.lib";
require RSAT::OrganismManager;
use LWP::Simple;

################################################################
## Main package
package main;
{
  ################################################################
  ## Initialise parameters
  our $start_time = &RSAT::util::StartScript();

  our %outfile = ();

  our $verbose = 0;
  our $out = STDOUT;

  my $def_supported_orgs_file = 'supported_organisms.tab.bk';
  my $def_genomes_path = 'data/genomes/';

  # read-only genome data precomputed for RSAT,
  # require $def_supported_orgs_file in place for taxon operations
  our @rsat_repos = (
    'https://rsat.eead.csic.es/plantsdata/'
  );

  # interactive Web servers with genomes in public_html/data/genomes/,
  # require $def_supported_orgs_file in place for taxon operations,
  # most offline in 2026
  our @rsat_servers = (
    "https://rsat.france-bioinformatique.fr/fungi",
    "http://prokaryotes.rsat.eu",
    "http://rsat.france-bioinformatique.fr/metazoa",
    "http://protists.rsat.eu",
    "http://plants.rsat.eu",
    "http://teaching.rsat.eu"
  );

  ## Default server. Can be changed with option -url
  $server_url = $rsat_repos[0]; 

  ## Output fields
  $return_fields = "";
  @return_fields = ();
  @supported_return_fields = @RSAT::OrganismManager::supported_org_fields;
  %supported_return_fields = ();
  foreach my $field (@supported_return_fields) {
    $supported_return_fields{$field} = 1;
  }
  $supported_return_fields = join ",", @supported_return_fields;

  ################################################################
  ## Read argument values
  &ReadArguments();

  ################################################################
  ## Check argument values
  
  unless ($server_url =~ /^http/) {
    RSAT::error::FatalError("Server URL should start with http[s]://");
  }
  if(grep(/$server_url/,@main::rsat_servers)) {
    $server_url .= "/$def_genomes_path";
  }

  ## Return fields
  if (scalar(@return_fields) > 0) {
    $args{return} = join (",", @return_fields);
  }

  ################################################################
  ## Open output stream
  $out = &OpenOutputFile($outfile{output});

  if($args{'servers'} == 1) {
    foreach my $s (@rsat_repos) {
      print "$s\t#repo\n";
    }
    foreach my $s (@rsat_servers) {
      print "$s\t#server\n";
    }


  } else {

    RSAT::message::TimeWarn("Querying server", $server_url) if ($main::verbose >= 2);
    RSAT::message::TimeWarn("Taxon", $args{'taxon'}) if ($main::verbose >= 2);

    my $line, $col, $ncol, $outstring;
    my @return_cols = ();
 
    my $urldata = get($server_url.$def_supported_orgs_file) ||
      RSAT::error::FatalError("Cannot access/find $server_url$def_supported_orgs_file, please contact rsat-contact\@list01.biologie.ens.fr");

    open(SUPORGS,'<', \$urldata) ||
      RSAT::error::FatalError("Cannot read $server_url$def_supported_orgs_file, please contact rsat-contact\@list01.biologie.ens.fr");
    while ($line = <SUPORGS>) { 

      if($line =~ m/^#/) {
        chomp $line;
	$line =~ s/^#//;

        if(!$args{return}) {
          $ncol = 0;		
	  foreach $col (split(/\s+/,$line)) {
            push(@return_cols, $ncol);
            $ncol++;
          }
        } else { # conserve user-defined field order
          foreach my $field (@return_fields) {
	    $ncol = 0;
            foreach $col (split(/\s+/,$line)) {
              if($col eq $field) {
                push(@return_cols, $ncol);
		last;
	      } 
	      $ncol++;
            }		    
	  }
	}

      } else {	      

	next if($args{'taxon'} && $line !~ m/$args{'taxon'}/);

	chomp $line;
	@cols = split(/\t/,$line);
 
        $outstring = '';	
        foreach $col (@return_cols) {
          $outstring .= "$cols[$col]\t"; 
        } 
	$outstring =~ s/\t$/\n/;
	
	print $out $outstring;
      }
    }

    close $out;
  }
  
  ################################################################
  ## Report execution time and close output stream
  my $exec_time = &RSAT::util::ReportExecutionTime($start_time);
  print $main::out $exec_time if ($main::verbose >= 1); 
  close $main::out if ($main::outfile{output});
  
  exit(0);
}

################################################################
#### Display full help message
sub PrintHelp {
  open HELP, "| more";
  print HELP <<End_of_help;
NAME
	supported-organisms-server

USAGE
        supported-organisms-server [-url server] [-o outputfile] [-v]

AUTHORS
	Bruno Contreras Moreira bcontreras\@eead.csic.es       	
	Jacques.van-Helden\@univ-amu.fr

DESCRIPTION

	Get the list of organisms supported on a remote RSAT
	server or genome repository. Optionally, the list of 
        supported organisms can be stricted at a given taxonomic 
        level (option -taxon).

CATEGORY
	Genomes

OPTIONS
	-h	 (must be first argument) display full help message

	-help	 (must be first argument) display options

        -servers Show available RSAT servers/genome repositores

	-url     Specify the URL of the remote RSAT server. 
                 Default: $server_url

		 The option -url can be combined with the option
		 -taxon in order to obtain the list of organisms
		 supported on the main RSAT server, before downloading
		 them.

		 Examples: 

                   supported-organisms-server -taxon Viridiplantae \
                      -return last_update,ID,taxonomy \
                      -server http://plants.rsat.eu

		 Use a read-only RSAT genome repository:		  

		   supported-organisms-server -url $server_url

 	-return  output fields
		 supported: $supported_return_fields

        -taxon   selected_taxon 
	         Only returns organisms belonging to a selected taxon.

End_of_help
  close HELP;
  exit;
}

################################################################
#### Display short help message #####
sub PrintOptions {
  open HELP, "| more";
  print HELP <<End_short_help;
template options
----------------
-h	 (must be first argument) display full help message
-help	 (must be first argument) display options
-servers show available RSAT servers/genome repositores
-o	 output file
-v	 verbose
-format	 output format ($supported_formats)
-return  output fields ($supported_return_fields)
-taxon   selected_taxon
-url     URL of the remote server (e.g. http://www.rsat.eu/)
End_short_help
  close HELP;
  exit;
}


################################################################
#### Read arguments 
sub ReadArguments {
  my $arg;
  my @arguments = @ARGV; ## create a copy to shift, because we need ARGV to report command line in &Verbose()
  
  while (scalar(@arguments) >= 1) {
    $arg = shift (@arguments);
    
=pod

=head1 OPTIONS

=over 4

=item B<-v #>

Level of verbosity (detail in the warning messages during execution)

=cut

    if ($arg eq "-v") {
      if (&IsNatural($arguments[0])) {
	$main::verbose = shift(@arguments);
      } else {
	$main::verbose = 1;
      }


=pod

=item B<-h>

Display full help message

=cut
    } elsif ($arg eq "-h") {
      &PrintHelp();


=pod

=item B<-help>

Same as -h

=cut
    } elsif ($arg eq "-help") {
      &PrintOptions();

=pod

=item B<-url http://[server_url/rsat/]>

URL of the RSAT server/repository to query.
Try -servers to find out list.

=cut

    } elsif (($arg eq "-url")
	     || ($arg eq "-server")) {
      $main::server_url = shift(@arguments);

      ## Output fields
    } elsif ($arg eq "-return") {
      $return_fields = shift(@arguments);
      chomp($return_fields);
      my @fields_to_return = split ",", $return_fields;
      foreach $field (@fields_to_return) {
	if ($supported_return_fields{$field}) {
	  push @return_fields, $field;
	} else {
	  &RSAT::error::FatalError(join("\t", $field, "Invalid return field. Supported:", $supported_return_fields));
	}
      }

      ## Root taxon
    } elsif ($arg eq "-taxon") {
      $args{taxon} = shift(@arguments);
=pod

=item	B<-servers #>

Show available RSAT servers/genome repositores.

=cut
    } elsif ($arg eq "-servers") {
      $args{servers} = 1;
=pod

=item	B<-o outputfile>

If no output file is specified, the standard output is used.  This
allows to use the command within a pipe.

=cut
    } elsif ($arg eq "-o") {
      $outfile{output} = shift(@arguments);
      
    } else {
      &FatalError("Invalid option", $arg);
      
    }
  }
}

