# module d'import de donnees vers geoserver via curl pour PERL

package rest_curl; 

use Exporter;

# CM TLD/ISPA Aout 2014
# v1.00 : 18/08/2014

use vars qw(@ISA @EXPORT $VERSION);


use strict;
use warnings;

use FileHandle;		# pour envoi de fichier à Curl
use File::stat;
use WWW::Curl::Easy;   	# pkg  libwww-curl-perl





#our $user="admin";
#our $password="geoserver";
#our $URL="http://sdeeph16:8080/geoserver/rest";



sub errorMessage
{
	my $errorCode=shift;

	# http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
	my %errors=();
	# Informational 1xx
	$errors{100}="Continue";
	$errors{101}="Switching Protocols";

	# Successful 2xx
	$errors{200}="OK";
	$errors{201}="Created";
	$errors{202}="Accepted";
	$errors{203}="Non-Authoritative Information";
	$errors{204}="No Content";
	$errors{205}="Reset Content";
	$errors{206}="Partial Content";

	# Redirection 3xx
	$errors{300}="Multiple Choices";
	$errors{301}="Moved Permanently";
	$errors{302}="Found";
	$errors{303}="See Other";
	$errors{304}="Not Modified";
	$errors{305}="Use Proxy";
	#$errors{306}="";
	$errors{307}="Temporary Redirect";

	# Client Error 4xx
	$errors{400}="Bad Request";
	$errors{401}="Unauthorized";
	$errors{402}="Payment Required";
	$errors{403}="Forbidden";
	$errors{404}="Not Found";
	$errors{405}="Method Not Allowed";
	$errors{406}="Not Acceptable";
	$errors{407}="Proxy Authentication Required";
	$errors{408}="Request Timeout";
	$errors{409}="Conflict";
	$errors{410}="Gone";
	$errors{411}="Length Required";
	$errors{412}="Precondition Failed";
	$errors{413}="Request Entity Too Large";
	$errors{414}="Request-URI Too Long";
	$errors{415}="Unsupported Media Type";
	$errors{416}="Requested Range Not Satisfiable";
	$errors{417}="Expectation Failed";


	# Server Error 5xx
	$errors{500}="Internal Server Error";
	$errors{501}="Not Implemented";
	$errors{502}="Bad Gateway";
	$errors{503}="Service Unavailable";
	$errors{504}="Gateway Timeout";
	$errors{505}="HTTP Version Not Supported";

	return $errors{$errorCode};
}


sub checkReturnCode
{
	my $curl=shift;
	my $retcode=shift;
	my $response_body=shift;

        # Looking at the results...
        if ($retcode == 0) {
                print("\t\tTransfer went ok\n");
                my $response_code = $curl->getinfo(CURLINFO_HTTP_CODE);
                # judge result and next action based on $response_code
                print("\t\tReceived response: \n$response_body\n");
        } else {
                # Error code, type of error, error message
                print("\t\tAn error happened: $retcode ".$curl->strerror($retcode)." ".$curl->errbuf."\n");
        }
}


# verifie si un coverage donne existe
sub checkCoverage
{
	my $URL=shift;
	my $user=shift;
	my $password=shift;
	my $curl=shift;
	my $workspaceName=shift;
	my $coveragestoreName=shift;
	my $coverage=shift;

	my $uri=$URL."/workspaces/$workspaceName/coveragestores/$coveragestoreName/coverages/$coverage.json";
	# args corrects ?
	# coverage ? 

	print "\n\ncheck coverage : uri = $uri\n";

	$curl->setopt(CURLOPT_HTTPHEADER,['Content-Type: text/xml']);
	$curl->setopt(CURLOPT_HEADER,1);
	$curl->setopt(CURLOPT_URL, $uri);
	$curl->setopt(CURLOPT_USERPWD, "$user:$password");
	$curl->setopt(CURLOPT_VERBOSE, 1);
	my $response_body;
        $curl->setopt(CURLOPT_WRITEDATA,\$response_body);
	$curl->setopt(CURLOPT_CUSTOMREQUEST,"GET");

        # Starts the actual request
       	my $retCode 	= $curl->perform;
	#print "\t retCode = $retCode\n";
	my $err 	= $curl->errbuf;
	#print "\t err = $err\n";
	my $info 	= $curl->getinfo(CURLINFO_HTTP_CODE);
	#print "\t info = $info\n";
	checkReturnCode($curl,$retCode,$response_body);

	return $info;
}


# recupere la liste des workspaces
sub getWorkspacesList
{
	my $URL=shift;
	my $user=shift;
	my $password=shift;
	my $curl=shift;


	my $uri=$URL."/workspaces.json";

	$curl->setopt(CURLOPT_HTTPHEADER,['Content-Type: text/xml']);
	$curl->setopt(CURLOPT_HEADER,1);
	$curl->setopt(CURLOPT_URL, $uri);
	$curl->setopt(CURLOPT_USERPWD, "$user:$password");
	$curl->setopt(CURLOPT_VERBOSE, 1);
	my $response_body;
        $curl->setopt(CURLOPT_WRITEDATA,\$response_body);
	$curl->setopt(CURLOPT_CUSTOMREQUEST,"GET");

        # Starts the actual request
       	my $retCode 	= $curl->perform;
	my $err 	= $curl->errbuf;
	my $info 	= $curl->getinfo(CURLINFO_HTTP_CODE);

	checkReturnCode($curl,$retCode,$response_body);


	# retourne du contenu JSON => il faut le traiter
	use JSON::PP;	# libjson-pp-perl
	# JSON : href

	# enleve l'entete HTML
	my @body=(split /\n/,$response_body);
	splice @body, 0,6 ; # remove first 6 
	$response_body=join ("\n",@body);

	#print "response_body : $response_body\n";


	my $response = decode_json($response_body);
	my @workspacesList=();

	foreach my $workspace ($response->{"workspaces"})
	{
		#print "\t workspace = $workspace\n";
	#	my @keys=keys %$ft; # {$response->{"featureTypes"}{$ft}};
		#print "keys = @keys\n"; 
		my $node=$workspace->{"workspace"};
		#print "\t workspace node = $node\n";
		#print "node = $node\n";
		foreach my $item (@$node)
		{
			#print "\t\t item = $item\n";
	#		my @keys=keys %$item; 
			#print "\t\t keys = @keys\n"; 
			my $name=$item->{"name"};
			#print "\t\t name = $name\n"; 
			push  @workspacesList,$name;
		}

		#last;
	}
	#exit;
	
	print "\t".scalar(@workspacesList)." workspaces existing\n";
	$curl->setopt(CURLOPT_CUSTOMREQUEST,""); # nettoyer pour ne pas perturber les POST
	return \@workspacesList;
}



# OK
sub createWorkspace
{
	my $URL=shift;
	my $user=shift;
	my $password=shift;
	my $curl=shift;
	my $workspaceName=shift;

	print "\t create workspace : $workspaceName\n";

	my $xmlStr="<workspace><name>$workspaceName</name></workspace>";
	#my $header="Content-type: application/xml"; # text/xml";	# 
        $curl->setopt(CURLOPT_HEADER,1);	# 1 = true : inclut le header dans la sortie


	#my @headers=($header);

	$curl->setopt(CURLOPT_HTTPHEADER,['Content-Type: text/xml']);	# OK
#	$curl->setopt(CURLOPT_HTTPHEADER,("Content-type: application/xml"));

        $curl->setopt(CURLOPT_URL, $URL."/workspaces.xml");
	$curl->setopt(CURLOPT_POST, 1); 	# si GET avant par customrequest : bloque le POST
	$curl->setopt(CURLOPT_CUSTOMREQUEST,"POST");
	$curl->setopt(CURLOPT_USERPWD, "$user:$password");
	$curl->setopt(CURLOPT_POSTFIELDS, $xmlStr);	# donnees envoyees lors du POST, envoi d'un fichier : @path
	$curl->setopt(CURLOPT_VERBOSE, 1);		# tres utile pour le debogage

	my $response_body;
        $curl->setopt(CURLOPT_WRITEDATA,\$response_body);
	# POST
	# Content-type text/xml
	# user 
	# données : corps

        # Starts the actual request
        my $retCode = $curl->perform;
	my $err = $curl->errbuf;
	my $info = $curl->getinfo(CURLINFO_HTTP_CODE);
	print " return code : $retCode\n";  	# OK : created : 201
	# cree quand meme ? 
	if ($retCode == 201)	{ print "\t workspace created\n"; }
	else 			{ print "\t ERROR creating workspace\n"; }
	#print "--- return code ---- \n";
	checkReturnCode($curl,$retCode,$response_body);
}



# OK partiel - en cours 
sub createDatastore
{
	my $URL=shift;
	my $user=shift;
	my $password=shift;
	my $curl=shift;
	my $workspaceName=shift;
	my $datastoreName=shift;
	my $type=shift;
	my $file=shift;
	my $fileType=shift;
	my $layerName=shift;

	my $xmlStr;
	my $opt;
	my $uri;
	my $zipFH;

	print "\t create datastore type = $type\n\n";
	
	if ($type eq "Postgis")
	{
		# OK
		$curl->setopt(CURLOPT_POST, 1);
		$curl->setopt(CURLOPT_CUSTOMREQUEST,"POST");
		$curl->setopt(CURLOPT_HTTPHEADER,['Content-Type: text/xml']);
		$xmlStr="<dataStore>  <name>$datastoreName</name>  <connectionParameters>     <host>147.100.98.16</host>    <port>5434</port>     <database>go_plus</database>     <user>go_plus</user>     <passwd>gogoFAST</passwd>     <dbtype>postgis</dbtype>   </connectionParameters> </dataStore>";  
		$uri=$URL."/workspaces/$workspaceName/datastores.xml";
		$curl->setopt(CURLOPT_POSTFIELDS, $xmlStr);
	}
	elsif ($type eq "Shapefile")
	{
		# configuration possible sans uploader de fichier ? a priori non
		#$xmlStr="<dataStore>  <name>$datastoreName</name> <type>Shapefile</type> </dataStore>";
		# local ? distant ? 
		print "\t\t file type : $fileType\n";
		if ($fileType eq "server")
		{
			# OK : utiliser CUSTOMREQUEST a "PUT" et POSTFIELDS
			# option curl 
			# curl -v -u admin:geoserver -XPUT -H "Content-type: text/plain"   -d "file:///data/shapefiles/rivers/rivers.shp" 
			#		http://localhost:8080/geoserver/rest/workspaces/acme/datastores/rivers/external.shp
			# curl -v -u admin:geoserver -XPUT -H "Content-type: text/plain"   -d "file:///home/spatialisation/chmoisy/Projets/IDS/Programmes/REST/ocs_gip.shp" 
			#		http://sdeeph16:8080/geoserver/rest/workspaces/test_curl/datastores/test_shapefile_curl_remote/external.shp
			# => OK mais couche renommé en ocs_gis car déjà présente dans le workspace (upload depuis le client) : test local 
			# 
			# -d : --data : data envoyé en requete POST
			# PUT uniquement
		 	## $curl->setopt(CURLOPT_PUT, 1);  # ne pas activer : CUSTOMREQUEST a la place
			# PUT 
		 	# TRUE pour que le chargement se fasse par HTTP PUT. Le fichier à charger doit être fixé avec les options CURLOPT_INFILE et CURLOPT_INFILESIZE. 
			# CURLOPT_INFILE 	Le fichier lu par le transfert lors du chargement. 



			# $curl->setopt(CURLOPT_HTTPHEADER,['Content-Type: text/xml']);
			$curl->setopt(CURLOPT_HTTPHEADER,['Content-Type: text/plain']);
			$uri=$URL."/workspaces/$workspaceName/datastores/$datastoreName/external.shp";		
			if (defined($layerName))
			{
				# changement de nom de couche ?	
			}			
			$xmlStr="file://".$file; # file path
			#$curl->setopt(CURLOPT_POSTFIELDS, $xmlStr);
			# client REST : 2eme option : file:///chemin/fichier.shp : BODY  : CURL_POSTFIELDS
			# comment le transferer ? quelle option ? curl -d "file:///chemin/fichier"
			# Expect: 100-continue
			$curl->setopt(CURLOPT_CUSTOMREQUEST,"PUT");
			# xmlStr ? 
			$curl->setopt(CURLOPT_POSTFIELDS, $xmlStr);  # mais on PUT, on ne POST pas : marcherais quand meme ?



			# CURLOPT_POSTFIELDS : Toutes les données à passer lors d'une opération de HTTP POST.



		}
		elsif ($fileType eq "local")
		{
			# OK
			# PUT : uniquement 
			$curl->setopt(CURLOPT_PUT, 1);

			$curl->setopt(CURLOPT_HTTPHEADER,['Content-Type: application/zip']);
			$uri=$URL."/workspaces/$workspaceName/datastores/$datastoreName/file.shp";
		
			
			$zipFH=FileHandle->new("<".$file);
			$curl->setopt(CURLOPT_INFILE, $zipFH);	# FileHandle : résultat ?  read function returned funny value 

			
		}
	}
	elsif ($type eq "ShapefileDirectory")
	{
		# OK import mais pb visualisation couche : erreur ? spécification SRS + recalcul emprise de la couche à faire
		# meme config external / Server
		$curl->setopt(CURLOPT_HTTPHEADER,['Content-Type: text/plain']);
		
		$xmlStr="file://".$file; # dir path
		$curl->setopt(CURLOPT_CUSTOMREQUEST,"PUT");

		$curl->setopt(CURLOPT_POSTFIELDS, $xmlStr);  # mais on PUT, on ne POST pas : marcherais quand meme ?

		$opt="?configure=all";
		$uri=$URL."/workspaces/$workspaceName/datastores/$datastoreName/external.shp$opt";

	}
	#my $header="Content-type: application/xml"; # text/xml";	# 
        $curl->setopt(CURLOPT_HEADER,1);	# 1 = true : inclut le header dans la sortie


	#$curl->setopt(CURLOPT_HTTPHEADER,['Content-Type: text/xml']);	# OK

        $curl->setopt(CURLOPT_URL, $uri); # $URL."/workspaces/$workspaceName/datastores.xml");
	#$curl->setopt(CURLOPT_POST, 1);
	$curl->setopt(CURLOPT_USERPWD, "$user:$password");
	#$curl->setopt(CURLOPT_POSTFIELDS, $xmlStr);	# donnees envoyees lors du POST, envoi d'un fichier : @path
	$curl->setopt(CURLOPT_VERBOSE, 1);		# tres utile pour le debogage

	my $response_body;
        $curl->setopt(CURLOPT_WRITEDATA,\$response_body);
	# POST
	# Content-type text/xml
	# user 
	# données : corps

        # Starts the actual request
        my $retCode 	= $curl->perform;
	my $err 	= $curl->errbuf;
	my $info 	= $curl->getinfo(CURLINFO_HTTP_CODE);


	if (defined($zipFH))	{ $zipFH->close();}

	checkReturnCode($curl,$retCode,$response_body);

}


# mise a jour des couches dans le datastore 
# 1 - specification SRS : <srs>EPSG:4326</srs> dans feature Type
# 2 - recalcul emprise
#
# bloque en attente des infos : cf XML fichier corrigé ?  => a ajouter ?

# OK avec content-type et enabled

sub updateFeatureType
{
	my $URL=shift;
	my $user=shift;
	my $password=shift;
	my $curl=shift;
	my $workspaceName=shift;
	my $datastoreName=shift;

	my $uri;
	my $opt;

	$opt="?list=all";
	#$uri=$URL."/workspaces/$workspaceName/datastores/$datastoreName/featuretypes.xml$opt";
	$uri=$URL."/workspaces/$workspaceName/datastores/$datastoreName/featuretypes.json$opt";				

	#list

	#The list parameter is used to control the category of feature types that are returned. It can take one of the following values:
	#    configured—Only configured feature types are returned. This is the default value.
	#    available—Only feature types that haven’t been configured but are available from the specified data store will be returned.
	#    available_with_geom—Same as available but only includes feature types that have a geometry attribute.
	#    all—The union of configured and available.


	#my $header="Content-type: application/xml"; 
	# SRS ? 
	$curl->setopt(CURLOPT_CUSTOMREQUEST,"GET");
	$curl->setopt(CURLOPT_HEADER,1);
	#$curl->setopt(CURLOPT_HTTPHEADER,['Content-Type: application/xml']);
        $curl->setopt(CURLOPT_URL, $uri); # $URL."/workspaces/$workspaceName/datastores.xml");
	$curl->setopt(CURLOPT_USERPWD, "$user:$password");

	$curl->setopt(CURLOPT_VERBOSE, 1);

	my $response_body;
        $curl->setopt(CURLOPT_WRITEDATA,\$response_body);

       	# Starts the actual request
        my $retCode 	= $curl->perform;
	my $err 	= $curl->errbuf;
	my $info 	= $curl->getinfo(CURLINFO_HTTP_CODE);

	#print "\n\n Response Body :\n";
	#my @response=$response_body;
	# remove header : first 6 lignes; response= 1 seul string 
	#my @body=(split /\n/,$response_body)[6..-1];
	#$response_body=join ('\n',@body);
	my @body=(split /\n/,$response_body);
	splice @body, 0,6 ; # remove first 6 
	$response_body=join ("\n",@body);
	#for my $idx (0..5) 
	#{
	#	my $body=(split /\n/,${response_body})[1..-1]; # supprime la partie avant le 1er saut de ligne : 1ere ligne 
	#	$response_body=$body;
	#}
	#print $response_body."\n\n"; # resultat = XML => lecture par lib
	
	#return;

	use JSON::PP;	# libjson-pp-perl
	# JSON : href
	
	my $response = decode_json($response_body);
	#print "response : $response\n";
	#foreach my $key (keys %{$response->{"featureTypes"}})
	#{
	#	print "\t $key => ".$response->{"featureTypes"}{$key}."\n";
	#}
	foreach my $ft ($response->{"featureTypes"})
	{
		#print "\t ft = $ft\n";
		my @keys=keys %$ft; # {$response->{"featureTypes"}{$ft}};
		#print "keys = @keys\n"; 
		my $node=$ft->{"featureType"};
		#print "node = $node\n";
		foreach my $item (@$node)
		{
			#print "\t\t item = $item\n";
			my @keys=keys %$item; 
			#print "\t\t keys = @keys\n"; 
			my $href=$item->{"href"};
			#print "\t\t href = $href\n"; 
	
		}

		#last;
	}

	my $vectorsList=$response->{"featureTypes"}{"featureType"};
	#print "vectors List = $vectorsList\n";

	# test 2eme :
	shift @$vectorsList;

	foreach my $vector (@$vectorsList)
	{

		# bloque en attente ? de quoi ? PUT => options ? param ? 

		# recup <atom => href=
		#print "vector = $vector\n";
		my $href=$vector->{"href"};
		$href=~ /(\S+)\.json$/;
		my $hrefP=$1.".xml";
		#my $xmlStr="<srs>EPSG:4326</srs>"; # < HTTP/1.1 400 Bad Request
		#my $xmlStr="<featureType><srs>EPSG:4326</srs></featureType>"; # < HTTP/1.1 400 Bad Request
	#	my $xmlStr="<featureType><srs>EPSG:4326</srs> <projectionPolicy>FORCE_DECLARED</projectionPolicy></featureType>"; # OK avec content-type   
		# nativeCRS ? pb header ? Content-type d'apres log : oui
		# pb disparation couche dans previsualisation : erreur publié mais non actif : recharger le type d'objet a faire manuellement ? puis activer : OK affichage
		# activation ? 
		my $xmlStr="<featureType><srs>EPSG:4326</srs> <projectionPolicy>FORCE_DECLARED</projectionPolicy> <enabled>true</enabled> </featureType>";  # OK

		my $name=$vector->{"name"};
		print " \n processing vector $name\n";
		#print "$name => $href\n";
		#next;

		my $opt="?recalculate=nativebbox,latlonbbox";
		my $uri=$hrefP.$opt;
		print " uri = $uri\n";
		#exit;
		#my $uri=$URL."/workspaces/$workspaceName/datastores/$datastoreName/featuretypes/$vector$opt";
		#$curl->setopt(CURLOPT_PUT, 1); 
		$curl->setopt(CURLOPT_HTTPHEADER,['Content-Type: application/xml']);

		$curl->setopt(CURLOPT_HEADER,1);

		$curl->setopt(CURLOPT_CUSTOMREQUEST,"PUT");

		$curl->setopt(CURLOPT_POSTFIELDS, $xmlStr);  # mais on PUT, on ne POST pas : marcherais quand meme ?

	        $curl->setopt(CURLOPT_URL, $uri); # $URL."/workspaces/$workspaceName/datastores.xml");

		$curl->setopt(CURLOPT_USERPWD, "$user:$password");

		$curl->setopt(CURLOPT_VERBOSE, 1);

		my $response_body;
	        $curl->setopt(CURLOPT_WRITEDATA,\$response_body);

	       	# Starts the actual request
	        my $retCode 	= $curl->perform;
		my $err 	= $curl->errbuf;
		my $info 	= $curl->getinfo(CURLINFO_HTTP_CODE);
		#exit;
	}
}




# en dev
# le coverage store est d'un format et d'un srs donné
# on ne peut pas mixer plusieurs fichiers avec des formats ou des srs différents
#
# 1 coverage store par coverage ou plusieurs coverage dans le meme coverage store ? 
#
sub createCoveragestore
{
	my $URL=shift;
	my $user=shift;
	my $password=shift;
	my $curl=shift;
	my $workspaceName=shift;
	my $coveragestoreName=shift;
	my $fileType=shift;
	my $type=shift;
	my $file=shift;
	my $proj=shift;
	my $layerName=shift||undef;
	my $configure=shift||undef;
	my $recalculate=shift||undef;
	my $enabled=shift||undef;

	#my $fileType=shift;
	#my $layerName=shift;

	my $uri;
	my $xmlStr;

	my $FH;

	print "\t create coverage store :\n";
	print "\t\t url=$URL\n";
	print "\t\t user=$user\n";
	print "\t\t password=$password\n";
	print "\t\t curl=$curl\n";
	print "\t\t workspace=$workspaceName\n";
	print "\t\t coveragestorename=$coveragestoreName\n";
	print "\t\t filetype=$fileType\n";
	print "\t\t type=$type\n";
	print "\t\t file=$file\n";
	print "\t\t proj=$proj\n";
	print "\t\t layername=$layerName\n";
	print "\t\t configure=$configure\n";
	print "\t\t recalculate=$recalculate\n";
	print "\t\t enable=$enabled\n";

	# imagemosaic : fichiers multiples : fichiers landsats eclatés ? fichiers aeroportes ? dalles IGN  => zip


	# ZIP : CURLOPT_PUT pour INFILE pas de CUSTOMREQUEST => pour champ POST

	# envi : forcer envihdr ?

	print "\nsending file $file \n\n";

	# abort if $file is not readable

	#unless (-r $file)	{ return -1 };
	#if (-r $file)	{ print  };
	#unless (-r $file)	{ print "\t\t !!!!! $file IS NOT READABLE\n";};

	if ( ($fileType eq "geotiff") || ($fileType eq "worldimage") ) 
	{
		$curl->setopt(CURLOPT_CUSTOMREQUEST,"PUT");
		$curl->setopt(CURLOPT_PUT, 1);
		$xmlStr="file://".$file;
	}
	elsif ($fileType eq "imagemosaic")
	{
		#$curl->setopt(CURLOPT_CUSTOMREQUEST,"POST");	# NOK pour external ?
		$curl->setopt(CURLOPT_CUSTOMREQUEST,"PUT");	# NOK pour external ?
		$curl->setopt(CURLOPT_PUT, 1);  
		$xmlStr="file://".$file;
	}
	else
	{
		#formats supported : geotiff, nitf, aig, dted, jp2ecw, ehdr, erdasimg, rpftoc, ecw, rst, gtopo30, arcgrid, imagemosaic, envihdr, worldimage 
		print "unknown type of image : =$fileType=\n";
		$curl->setopt(CURLOPT_PUT, 1);
		$curl->setopt(CURLOPT_CUSTOMREQUEST,"PUT");
		$xmlStr="file://".$file;
	}

	#if ($type eq "local")
	# fichier present sur le serveur : donner le chemin du fichier
	if ($type eq "server")
	{
		$curl->setopt(CURLOPT_HTTPHEADER,['Content-Type: application/txt']);
		$uri=$URL."/workspaces/$workspaceName/coveragestores/$coveragestoreName/external.".$fileType;
		#if (defined($layerName))
		#{
		#	$uri.="?coverageName=$layerName";
		#	print "\t\t ==> changing coverage name to =$layerName=\n";
		#}
		$curl->setopt(CURLOPT_CUSTOMREQUEST,"PUT");
		$curl->setopt(CURLOPT_PUT, 0); # on désactive au cas où ce serait activé avant
		$curl->setopt(CURLOPT_POSTFIELDS, $xmlStr);

		print "\t transfert $type \t image = $fileType \t ref = $xmlStr\n";
	}
	#elsif ($type eq "server")
	elsif ($type eq "local")
	{
		# zip ? 
		# fichier present sur le client : envoyer en zip ou autre ?
		

		$uri=$URL."/workspaces/$workspaceName/coveragestores/$coveragestoreName/file.".$fileType;

		# si le nom de la couche est defini, on renomme le nom du raster
		#if (defined($layerName))
		#{
		#	$uri.="?coverageName=$layerName";
		#	print "\t\t ==> changing coverage name to =$layerName=\n";
		#}

		# extension zip or other ? 
		my $ext =(split/\./,$file)[-1];
		if ($ext eq "zip")
		{
			print "sending zip file\n";
			$curl->setopt(CURLOPT_HTTPHEADER,['Content-Type: application/zip']);
			#$curl->setopt(CURLOPT_CUSTOMREQUEST,"PUT");
		}
		elsif (($ext eq "tif") || ($ext eq "tiff") )
		{
			print "sending tif file\n";
			$curl->setopt(CURLOPT_HTTPHEADER,['Content-Type: image/geotiff']);	
			#$curl->setopt(CURLOPT_CUSTOMREQUEST,"PUT");
		}
		else
		{
			print "sending binary file\n";
			$curl->setopt(CURLOPT_HTTPHEADER,['Content-Type: application/octet-stream']);	
			#$curl->setopt(CURLOPT_CUSTOMREQUEST,"PUT"); # ? 
		}
		$FH=FileHandle->new("<".$file);	# ouverture en binaire ?
		binmode($FH);
		$curl->setopt(CURLOPT_PUT, 1);
		$curl->setopt(CURLOPT_CUSTOMREQUEST,"PUT");
		$curl->setopt(CURLOPT_INFILE, $FH);
		print "sending file $file with filehandle $FH\n";
	}
	else
	{
		print "unknown transfert type : =$type=\n";
	}

	if (defined($configure))
	{
		#print "\t\t uri before configure : $uri\n";
		if ($uri=~ /\.$fileType$/)
		{
			$uri.="?configure=$configure";
		}
		else
		{
			$uri.=",configure=$configure";
		}
		#print "\t\t uri after configure : $uri\n";
	}
	if (defined($recalculate))
	{
		# si pas d'autre argument : on ajoute ? 
		if ($uri=~ /\.$fileType$/)
		{
			$uri.="?recalculate=$recalculate";
		}
		else
		{
			# sinon : on le met a la suite des autres avec ,
			$uri.=",recalculate=$recalculate";
		}
	}
	# coverageName en dernier car si autre arg => pris comme nom
	if (defined($layerName))
	{
		if ($uri=~ /\.$fileType$/)
		{
			$uri.="?coverageName=$layerName";
		}
		else
		{
			# sinon : on le met a la suite des autres avec ,
			$uri.=",coverageName=$layerName";
		}

		#$uri.="?coverageName=$layerName";
		print "\t\t ==> changing coverage name to =$layerName=\n";
	}


	#$curl->setopt(CURLOPT_POSTFIELDS, $xmlStr);  # mais on PUT, on ne POST pas : marcherais quand meme ?


        $curl->setopt(CURLOPT_HEADER,1);	# 1 = true : inclut le header dans la sortie


	#$curl->setopt(CURLOPT_HTTPHEADER,['Content-Type: text/xml']);	# OK

        $curl->setopt(CURLOPT_URL, $uri); # $URL."/workspaces/$workspaceName/datastores.xml");
	#$curl->setopt(CURLOPT_POST, 1);
	$curl->setopt(CURLOPT_USERPWD, "$user:$password");
	#$curl->setopt(CURLOPT_POSTFIELDS, $xmlStr);	# donnees envoyees lors du POST, envoi d'un fichier : @path
	$curl->setopt(CURLOPT_VERBOSE, 1);		# tres utile pour le debogage

	my $response_body;
        $curl->setopt(CURLOPT_WRITEDATA,\$response_body);

	#if (defined($FH))	{print "about to send file $file with filehandle $FH\n"; }

        # Starts the actual request
        my $retCode 	= $curl->perform;
	my $err 	= $curl->errbuf;
	my $info 	= $curl->getinfo(CURLINFO_HTTP_CODE);

	if (defined($FH))	{ $FH->close();}

	print "\ncreate coverage store : return code = $retCode\n";

	checkReturnCode($curl,$retCode,$response_body);

	

#exit;
	# si activation demandee
	if ((defined($enabled)) && ($enabled eq "ENABLE"))
	{

		print "\n\n";

		# modif : 
		# PUT sur coverage store: le SRS doit etre coherent entre toutes les images : non si modif coverage
		# si pas de nom de couche, on utilise le 
		unless (defined($layerName))
		{
			$file=~/\/(\w+)\.\w+?$/;
			$layerName=$1 || $coveragestoreName; 
		}
		# par defaut : EPSG:4326 / WGS84 Lat/Lon
		unless (defined($proj))
		{
			$proj="4326";
		}
		$uri=$URL."/workspaces/$workspaceName/coveragestores/$coveragestoreName/coverages/$layerName.xml";
		print "\t uri = $uri\n";
		$xmlStr="<coverage><srs>EPSG:$proj</srs> <projectionPolicy>FORCE_DECLARED</projectionPolicy> <enabled>true</enabled> </coverage>";
		print "\t xml = $xmlStr\n";
		# Erreur 500
		# This is unexpected, the layer seems to be mis-configured

		$curl->setopt(CURLOPT_HTTPHEADER,['Content-Type: text/xml']);
		$curl->setopt(CURLOPT_HEADER,1);
		$curl->setopt(CURLOPT_URL, $uri);
		$curl->setopt(CURLOPT_USERPWD, "$user:$password");
		$curl->setopt(CURLOPT_VERBOSE, 1);
		my $response_body2;
	        $curl->setopt(CURLOPT_WRITEDATA,\$response_body2);
		$curl->setopt(CURLOPT_POSTFIELDS, $xmlStr);
		$curl->setopt(CURLOPT_CUSTOMREQUEST,"PUT");

	        # Starts the actual request
        	my $retCode2 	= $curl->perform;
		my $err2 	= $curl->errbuf;
		my $info2 	= $curl->getinfo(CURLINFO_HTTP_CODE);

		checkReturnCode($curl,$retCode2,$response_body2);

	}

	return ($response_body);
}


1;
