#!/opt/local/bin/perl

# 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.

use strict;
#use SOAP::Lite +trace;
use SOAP::Lite;
use HTTP::Cookies;
use URI;
use Getopt::Long;

use lib '/opt/local/sympa/bin';
# use Conf;
use Commands;
use Conf;
use Auth;
use SympaSession;
use Language;
use Log;
use mail;
use MIME::QuotedPrint;
use List;
use Message;
use admin;
use Config_XML;
use Family;
use report;
use File::Copy;
use tools;
use tt2;
use Sympa::Constants;


my ($reponse, @ret, $val, %fault);


my $usage = "$0 is a perl soap client for Sympa for TEST ONLY. Use it to illustrate how to
code access to features of Sympa soap server. Authentication can be done via
user/password or user cookie or as a trusted remote application

Usage: $0 <with the following options:>
--soap_url=<soap sympa server url>
--service=<a sympa service>
--trusted_application=<app name>
--trusted_application_password=<password>
--proxy_vars=<id=value,id2=value2>
--service_parameters=<value1,value2,value3>


OR usage: $0 <with the following options:>
--soap_url=<soap sympa server url>
--user_email=<email>
--user_password=<password>
--session_id=<sessionid>
--service=<a sympa service>
--service_parameters=<value1,value2,value3>


OR usage: $0 <with the following options:>
--soap_url=<soap sympa server url>
--cookie=<sympauser cookie string>

Example:
$0 --soap_url=<soap sympa server url> --cookie=sympauser=someone\@cru.fr
";

my %options;
unless (&GetOptions(\%main::options, 'soap_url=s', 'service=s', 'trusted_application=s', 'trusted_application_password=s','user_email=s', 'user_password=s','cookie=s','proxy_vars=s','service_parameters=s','session_id=s')) {
    printf "";
}


my $soap_url = $main::options{'soap_url'};
unless (defined $soap_url){
    printf "error : missing soap_url parameter\n";
    printf $usage;
    exit;
}

my $user_email = $main::options{'user_email'};
my $user_password =$main::options{'user_password'};
my $session_id = $main::options{'session_id'};
my $trusted_application =$main::options{'trusted_application'};
my $trusted_application_password =$main::options{'trusted_application_password'};
my $proxy_vars=$main::options{'proxy_vars'};
my $service=$main::options{'service'};
my $service_parameters=$main::options{'service_parameters'};
my $cookie=$main::options{'cookie'};

if (defined $trusted_application) {
    unless (defined $trusted_application_password) {
	printf "error : missing trusted_application_password parameter\n";
	printf $usage;
	exit;
    }
    unless (defined $service) {
	printf "error : missing service parameter\n";
	printf $usage;
	exit;
    }
    unless (defined $proxy_vars) {
	printf "error : missing proxy_vars parameter\n";
	printf $usage;
	exit;
    }

    &play_soap_as_trusted($soap_url, $trusted_application,  $trusted_application_password, $service, $proxy_vars, $service_parameters);
}elsif($service eq 'getUserEmailByCookie'){
  &play_soap(soap_url => $soap_url, 
	     session_id => $session_id,
	     service => $service);

}elsif(defined $cookie){
    printf "error : get_email_cookie\n";
     &get_email($soap_url, $cookie);
     exit;
}else{
    unless (defined $session_id || (defined $user_email && defined  $user_password)){
	printf "error : missing session_id OR user_email+user_passwors  parameters\n";
	printf $usage;
	exit;
    }

    &play_soap(soap_url => $soap_url, 
	       user_email => $user_email, 
	       user_password => $user_password, 
	       session_id => $session_id,
	       service => $service,
	       service_parameters => $service_parameters);
}

sub play_soap_as_trusted{
    my $soap_url=shift;
    my $trusted_application=shift;
    my $trusted_application_password=shift;
    my $service=shift;
    my $proxy_vars=shift;
    my $service_parameters=shift;

    my $soap = new SOAP::Lite();    
    $soap->uri('urn:sympasoap');
    $soap->proxy($soap_url);

    my @parameters; 
    @parameters= split(/,/,$service_parameters) if (defined $service_parameters);
    my $p= join(',',@parameters);
    printf "calling authenticateRemoteAppAndRun( $trusted_application, $trusted_application_password, $proxy_vars,$service,$p)\n";

    my $reponse = $soap->authenticateRemoteAppAndRun( $trusted_application, $trusted_application_password, $proxy_vars,$service,\@parameters);
    &print_result($reponse);
}

sub get_email {
     my $soap_url=shift;
     my $cookie=shift;

    my ($service, $reponse, @ret, $val, %fault);

    ## Cookies management
    # my $uri = new URI($soap_url);
    
#    my $cookies = HTTP::Cookies->new(ignore_discard => 1,
#				     file => '/tmp/my_cookies' );
#    $cookies->load();
    printf "cookie : %s\n", $cookie;

     
    my $soap = new SOAP::Lite();
    #$soap->on_debug(sub{print@_});
    $soap->uri('urn:sympasoap');
     $soap->proxy($soap_url);
#,		 cookie_jar =>$cookies);

    print "\n\ngetEmailUserByCookie....\n";
    $reponse = $soap->getUserEmailByCookie($cookie);
    &print_result($reponse);
exit;
  
 }

sub play_soap{
  my %param = @_;

  my $soap_url = $param{'soap_url'};
  my $user_email = $param{'user_email'};
  my $user_password = $param{'user_password'};
  my $session_id = $param{'session_id'};
  my $service = $param{'service'};
  my $service_parameters = $param{'service_parameters'};  
  
  my ($reponse, @ret, $val, %fault);

    ## Cookies management
    # my $uri = new URI($soap_url);
    
    my $cookies = HTTP::Cookies->new(ignore_discard => 1,
				     file => '/tmp/my_cookies' );
    $cookies->load();
    printf "cookie : %s\n", $cookies->as_string();

    my @parameters; 
    @parameters= split(/,/,$service_parameters) if (defined $service_parameters);
    my $p= join(',',@parameters);
    foreach my $tmpParam (@parameters) {
	printf "param: %s\n", $tmpParam;
    }

    # Change to the path of Sympa.wsdl
    #$service = SOAP::Lite->service($soap_url);
    #$reponse = $service->login($user_email,$user_password);
    #my $soap = SOAP::Lite->service($soap_url);
     
    my $soap = new SOAP::Lite() || die;
    #$soap->on_debug(sub{print@_});
    $soap->uri('urn:sympasoap');
    $soap->proxy($soap_url,
		 cookie_jar =>$cookies);

  ## Do the login unless a session_id is provided
  if ($session_id) {
    print "Using Session_id $session_id\n";

  }else {
    print "LOGIN....\n";

    #$reponse = $soap->casLogin($soap_url);
    $reponse = $soap->login($user_email,$user_password);
    $cookies->save;
    &print_result($reponse);
    $session_id = $reponse->result;
  }    
    
  ## Don't use authenticateAndRun for lists command

  ## Split parameters
  my @parameters=split /,/,$service_parameters;

    if ($service eq 'lists') {
      printf "\n\nlists....\n";
      $reponse = $soap->lists();

    }elsif ($service eq 'subscribe') {
      printf "\n\n$service....\n";      
      $reponse = $soap->subscribe(@parameters);

    }elsif ($service eq 'signoff') {
      printf "\n\n$service....\n";      
      $reponse = $soap->signoff(@parameters);

    }elsif ($service eq 'add') {
      printf "\n\n$service....\n";      
      $reponse = $soap->add(@parameters);

    }elsif ($service eq 'del') {
      printf "\n\n$service....\n";      
      $reponse = $soap->del(@parameters);

    }elsif ($service eq 'getUserEmailByCookie') {
      printf "\n\n$service....\n";
      $reponse = $soap->getUserEmailByCookie($session_id);

    }else {
      printf "\n\nAuthenticateAndRun service=%s;(session_id=%s)....\n",$service,$session_id;
      $reponse = $soap->authenticateAndRun($user_email,$session_id,$service,\@parameters);
    }

    &print_result($reponse);
    
}

sub print_result {
    my $r = shift;

# If we get a fault
    if (defined $r && $r->fault) {
	print "Soap error :\n";
	my %fault = %{$r->fault};
	foreach $val (keys %fault) {
	    print "$val = $fault{$val}\n";
	}
    }else {
	if (ref( $r->result) =~ /^ARRAY/) {
	    #printf "R: $r->result\n";
	    @ret = @{$r->result};
	}elsif (ref $r->result) {
	    printf "Pb $r->result\n";
	    return undef;
	}else {
	    @ret = $r->result;
	}
	&tools::dump_var(\@ret, 0, \*STDOUT);
    }

    return 1;
}
