#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# This file is part of G-language Genome Analysis Environment package
#
#     Copyright (C) 2001-2013 Keio University
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# 
#   $Id: EPCR.pm,v 1.1.1.1 2002/04/02 20:25:44 gaou Exp $
#
# G-language GAE 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.
# 
# G-language GAE 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 G-language GAE -- see the file COPYING.
# If not, write to the Free Software Foundation, Inc.,
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# 
#END_HEADER
#

package G::Tools::WebServices;

use SubOpt;
use G::Messenger;

use strict;
use base qw(Exporter);
use SelfLoader;

use LWP::Simple;

our @EXPORT = qw(
		 ws
		 keggapi
		 togoWS
		 emboss
		 seqret
		 blastall
		 );


__DATA__


#:::::::::::::::::::::::::::::::::
#       Perldoc
#:::::::::::::::::::::::::::::::::


=head1 NAME

    G::Tools::WebServices - Interface to web services, including BioMOBY and TogoWS

=head1 DESCRIPTION

    This class is a part of G-language Genome Analysis Environment, 
    collecting interfaces to web services.

=cut



#:::::::::::::::::::::::::::::::::
#       Let the code begin...
#:::::::::::::::::::::::::::::::::

=head2 emboss

 Name: emboss   -   run EMBOSS applications and KBWS via REST service

 Description:
    This is a wrapper around EMBOSS REST service provided at
    http://rest.g-language.org/emboss/.
    See the above website for details.

    Basically, this function behaves likewise the EMBOSS commandline applications.
    When images are produced, returned value is a URL.

 Usage:
    text result = emboss('program name', -option1=>value1);

    For example, to run seqret on a local file and to output the result in GenBank format,
    $result = emboss('seqret', 'local.file', -osformat2=>'genbank', -feature=>1);

 Options:
    Depends on the EMBOSS programs. See tfm (manual) of each program.  

 References:
   1. Rice P, Longden I, Bleasby A (2000) "EMBOSS: the European Molecular Biology Open
      Software Suite.", Trends Genet., 16(6):276-277.

 Author: 
    Kazuharu Arakawa (gaou@sfc.keio.ac.jp)

 History:
   20120830-01 initial posting

=cut

sub emboss{
    opt_default();
    my @args = opt_get(@_);
    my $program = shift;

    my @argv;
    my %file;
    my $i = 1;

    for my $tmp (@args){
	if(-e $tmp){
	    $file{"file$i"} = [$tmp];
	    $i ++;
	}else{
	    push(@argv, $tmp);
	}
    }

    my %options = opt_val();

    foreach my $key (keys %options){
	if ($options{$key} eq '1'){
	    push(@argv, '-' . $key);
	}else{
	    push(@argv, $key . '=' . $options{$key});
	}
    }

    require LWP::UserAgent;
    my $ua = LWP::UserAgent->new;
    my $response = $ua->post("http://rest.g-language.org/emboss/",
			     Content_Type=>'multipart/form-data',
			     Content=>[ %file, 'arg'=>join('/', @argv)]
			     );

    if ($response->is_redirect) {
	return $response->header('Location');
    }elsif ($response->is_success) {
	return $response->content;
    }else{
    	die $response->status_line;
    }

}


sub seqret{
    warn("This method is deprecated. Use emboss() instead.");
    emboss('seqret', @_);
}

sub blastall{
    warn("This method is deprecated. Use emboss('kblast') instead.");
    emboss('kblast', @_);
}


=head2 keggapi

 Name: keggapi   -   runs KEGG API

 Description:
    This is a wrapper around KEGG API REST wrapper, provided at
    http://rest.g-language.org/keggapi/.

    Refer to the official KEGG API web site for detailed documentations.
    http://www.genome.jp/kegg/soap/doc/keggapi_manual.html
    
 Usage:
    ex. 
    @list_of_services = keggapi();

    @list_of_pathways = keggapi('get_pathways_by_compounds', 'C00668');
    #Note that cpd: for compound ID is optional. Likewise for ec:, gl:, dr:

 Options:
    None.

 Author: 
    Kazuharu Arakawa (gaou@sfc.keio.ac.jp)

 History:
   20100123-01 initial posting

=cut

sub keggapi{
    my $program = shift;
    return readFile('http://rest.g-language.org/keggapi/' . $program . '/' . join('/', @_), 1);
}

=head2 togoWS

 Name: togoWS   -   runs togoWS REST web services

 Description:
    This is a wrapper around togoWS REST web services provided at
    http://togows.dbcls.jp/.
    
 Usage:
    #search
    @ids = togoWS(-search=>"keyword", -db=>"database");

    #entry
    $entry = togoWS(@ids);

 Options:
    -search  required option for keyword searching. 
    -db      name of the database for searching and entry retrieval
             required for searching, but not required for entry 
             retrieval, since corresponding database is automatically
             selected from the ID format. However, majority of the 
             databases simply use large numbers as IDs, which all
             result in "pubmed" as the databases. Therefore, use 
             of this option is necessary for IDs that are only numbers.
    -field   field name for entry retrieval (optional)
    -format  format name for entry retrieval (optional)

 Author: 
    Kazuharu Arakawa (gaou@sfc.keio.ac.jp)

 History:
   20090313-01 initial posting

=cut


sub togoWS{
    opt_default(db=>'', format=>'', field=>'', search=>'');
    my @args = opt_get(@_);
    my %opt = opt_val();

    if(length $opt{search}){
	$opt{db} = 'uniprot' unless(length $opt{db});
	return split(/\n/, get('http://togows.dbcls.jp/search/' . $opt{db} . '/' . $opt{search}));
    }else{
	unless(length $opt{db}){
	    if($args[0] =~ /^K\d+$/){
		$opt{db} = 'orthology';
	    }elsif($args[0] =~ /^\d\.\d+\.\d+\.\d+$/){
		$opt{db} = 'enzyme';
	    }elsif($args[0] =~ /^C\d+$/){
		$opt{db} = 'compound';
	    }elsif($args[0] =~ /^D\d+$/){
		$opt{db} = 'drug';
	    }elsif($args[0] =~ /^G\d+$/){
		$opt{db} = 'glycan';
	    }elsif($args[0] =~ /^R\d+$/){
		$opt{db} = 'reaction';
	    }elsif($args[0] =~ /^[A-Z][A-Z]_\d+$/){
		$opt{db} = 'nuccore';
	    }elsif($args[0] =~ /^BIOMD\d+$/){
		$opt{db} = 'biomodels';
	    }elsif($args[0] =~ /^MODEL\d+$/){
		$opt{db} = 'biomodels';
	    }elsif($args[0] =~ /^GO:\d+$/){
		$opt{db} = 'go';
	    }elsif($args[0] =~ /^IPR\d+$/){
		$opt{db} = 'interpro';
	    }elsif($args[0] =~ /^REACT_\d+$/){
		$opt{db} = 'reactome';
	    }elsif($args[0] =~ /^[a-zA-Z0-9]+_[a-zA-Z0-9*]+$/){
		$opt{db} = 'uniprot';
	    }else{
		$opt{db} = 'pubmed';
	    }
	}

	@args = readFile('http://rest.g-language.org/gbp/wild.pl?id=' . $args[0], 1) if($args[0] =~ /\*/);

	my $url = 'http://togows.dbcls.jp/entry/' . $opt{db} . '/' . join(',', @args);
	$url .= '/' . $opt{field} if (length $opt{field});
	$url .= '.' . $opt{format} if (length $opt{format});

	return get($url);
    }
    
}




=head2 ws

 Name: ws   -   runs web services through BioMOBY

 Description:
    This is a wrapper around MOBY::Client::Service to run web services
    through BioMOBY. Use help -w <keyword> to search for web services,
    help -w <service name> to view service description. 

    To use this function, you must first install MOBY::Client::Central
    module from CPAN. 
    
 Usage:
    ws(<service_name>, $argument1=>$ontology_or_namespace, ...);

    arguments are given as hash, where the key is the argument and the 
    value is the MOBY ontology or Namespace.

    ex: 
      ws('MOBYSHoundGetGenBankWhateverSequence', 'EX5B_ECOLI'=>'Swiss-Prot')

 Options:
    None.  

 References:
   1. Wilkinson MD, Links M (2002) "BioMOBY: an open source biological web services
      proposal.", Brief Bioinform., 3(4):331-341.
   2. Wilkinson M, Schoof H, Ernst R, Haase D (2005) "BioMOBY successfully integrates 
      distributed heterogeneous bioinformatics Web Services. The PlaNet exemplar case.",
      Plant Physiol., 138(1):5-17.

 Author: 
    Kazuharu Arakawa (gaou@sfc.keio.ac.jp)

 History:
   20080227-01 initial posting

=cut


sub ws {
    my $service = shift;

    eval{
	require MOBY::Client::Central;
	require MOBY::Client::Service;
    };
    if($@){
	croak "MOBY::Client::Central does not seem to be installed. Try'cpan MOBY::Client::Central' to install this module to enable BioMOBY support.";
    }

    my $m = MOBY::Client::Central->new();
    my %ns = %{$m->retrieveNamespaces()};

    my ($sv, $reg) = $m->findService(serviceName=>$service);
    die("Web Service: $service not found.") unless($sv);

    my @inputlist;
    my %hash = @_;
    
    foreach my $input (@{$$sv[0]->{input}}){
	my ($query, $name) = each %hash;
	last unless($query);

	my $article = $input->articleName();
	my $xml = ($ns{$name}) ? '<Object id="'.$query.'" namespace="'.$name.'"/>' : '<'.$name.' id="'.$query.'"/>';
	push(@inputlist, [$article, $xml]);
    }

    my $wsdl = $m->retrieveService($$sv[0]);
    my $serv = MOBY::Client::Service->new( service => $wsdl );
    my $result =  $serv->execute(XMLinputlist => [@inputlist]);

    $result =~ s/\n/=%=/g;

    if($result =~ /<moby:Simple.*?>(.*)<\/moby:Simple>/){
	my $res = $1;
	$res =~ s/=%=/\n/g;
	return $res;
    }

}





1;
