#
# Copyright for the Uniform Repository Service (c) 1995 - 2025
# by Gerald Banon. All rights reserved.
# Version 2.1
# resolve.tcl
#
# Created by GJFB in 2025-09-06 from an old version of from.tcl
#
# If the document is in the distributed collection defined by the local bibliographic mirror
# (unless the call is done from another mirror), it is returned,
# otherwise it is searched within the scope of the whole URLib collection
#
# Examples:
if 0 {
	http://mtc-m12.sid.inpe.br/urn:doi:10.17487/RFC8141?ibiurl.clientinformation.citingitem=urlib.net/www/2023/06.03.21.17&linktype=relative
	http://urlib.net/urn:doi:10.17487/RFC8141?ibiurl.clientinformation.citingitem=urlib.net/www/2023/06.03.21.17&linktype=relative
	http://gjfb0520.sid.inpe.br/urn:doi:10.1590/0001-3765202320210807?ibiurl.clientinformation.citingitem=urlib.net/www/2023/11.16.13.37&linktype=relative
	http://gjfb:1905/urn:doi:10.1590/0001-3765202320210807?ibiurl.clientinformation.citingitem=urlib.net/www/2023/11.16.13.37&linktype=relative
# in both URL below upn:4CR88AP no longer exist
#	http://gjfb:1905/upn:4CR88AP:QABCDSTQQW/4BT93R5?ibiurl.clientinformation.citingitem=iconet.com.br/banon/2001/04.28.19.50&linktype=relative
#	http://gjfb:1905/upn:4CR88AP-:QABCDSTQQW/4BT93R5?ibiurl.clientinformation.citingitem=iconet.com.br/banon/2001/04.28.19.50&linktype=relative
}
# this sort of URL must call the solve cgi script
proc Resolve {} {
if [catch {
	global env
## OBS: resolverID == uriPrefix (values are not upn:4CR88AP but can be relative to IBI, e.g. upn:4E9948J initially from mtc-m21c.sid.inpe.br))
# OBS: resolverID == uriPrefix (values are not ibi but can be relative to IBI, e.g. upn:4E9948J initially from mtc-m21c.sid.inpe.br))
# resolverID and destination
#	regexp {^/(.+:.+):(.+)$} $env(PATH_INFO) m resolverID destination ;# used with urn:doi only
	regexp {([^/]+):(.+)$} $env(PATH_INFO) m resolverID destination	;# used with urn:doi and doi
# ibiResolver (localSite)
	set ibiResolver $env(SERVER_NAME):$env(SERVER_PORT)
# homePath
	set homePath $env(DOCUMENT_ROOT)
# URLibServiceRepository
	set URLibServiceRepository $env(URLIB_SERVICE_REP)
# localSite
	set localSite $env(SERVER_NAME):$env(SERVER_PORT)
	
	source $homePath/col/$URLibServiceRepository/doc/utilities1.tcl	;# StoreArray
		
if 0 {	 	
	puts {Content-Type: text/html}
	puts {}
	puts $env(PATH_INFO)	;# => /urn:doi:10.17487/RFC8141
	puts 
	puts $resolverID		;# => urn:doi
	puts 
	puts $destination		;# 10.17487/RFC8141
}
# Store xxx C:/tmp/bbb.txt auto 0 a
	if {[info exists env(QUERY_STRING)] && [string compare {} $env(QUERY_STRING)] != 0} {
		set queryString ?$env(QUERY_STRING)
	} else {
		set queryString {}
	}
	if ![info exists resolverID] {
		puts "Location: http://$ibiResolver/customizeerror.cgi/603"
		puts ""
		return
	}
	
	if [string equal {urn:ibi} $resolverID] {
		puts "Location: http://$ibiResolver/customizeerror.cgi/602"
		puts ""
	}
	
if 0 {	 	
	puts 
	puts --$queryString--	;# => --?ibiurl.clientinformation.citingitem=urlib.net/www/2023/06.03.21.17--
}
if 0 {
	set url http://$localSite/ibi/$destination$queryString
	puts "Location: $url"
	puts ""
	return
}
	package require http
	set startingTime 02:00:00
	set startingSecond [clock scan $startingTime -base 109306800]
	set seconds [clock seconds]
	set timePeriod [expr 24*60*60]	;# 1 day
# 1 namespacePrefixXresolverURLarray
if 0 {	
# manual update of namespacePrefixXresolverURLarray
	set namespacePrefixXresolverURLarray(upn:4CR88AP) $ibiResolver	;# added by GJFB in 2025-06-11
	set namespacePrefixXresolverURLarray(upn:4CR88AP-) $ibiResolver	;# added by GJFB in 2025-06-11
	set namespacePrefixXresolverURLarray(urn:doi) doi.org	;# added by GJFB in 2023-12-26
#	set namespacePrefixXresolverURLarray(purl) purl.org
} else {
# automatic update of namespacePrefixXresolverURLarray
	if [file exists $homePath/col/$URLibServiceRepository/auxdoc/namespacePrefixXresolverURLarray.tcl] {
		source $homePath/col/$URLibServiceRepository/auxdoc/namespacePrefixXresolverURLarray.tcl	;# set namespacePrefixXresolverURLarray cache
	}
	
	ConditionalSet outputValue namespacePrefixXresolverURLarray($resolverID) {}
	
# similar code in ComputeFileUpdateFlag
	set mtime [lindex $outputValue 1]
	if [string equal {} $mtime] {set mtime 0}
	if {[expr ($seconds - $startingSecond)/$timePeriod] != [expr ($mtime - $startingSecond)/$timePeriod]} {
# since the last update (mtime), at least one transition time has occured
# where the transition times is = {starting second + n * time period: n = 0, 1, ...}
# old array input value, the input value should be updated
# UPDATE
# see: Returning the resolver URL of a given namespace prefix
#		set url http://gjfb:1905/col/urlib.net/www/2025/09.08.04.08/doc/script.cgi?namespaceprefix=upn:4E9948J
#		set url http://$ibiResolver/col/urlib.net/www/2025/09.08.04.08/doc/script.cgi?namespaceprefix=$resolverID
		set url http://urlib.net/col/urlib.net/www/2025/09.08.04.08/doc/script.cgi?namespaceprefix=$resolverID
		if [catch {http::geturl $url} token] {
# nothing to do		
		} else {
			if {[http::ncode $token] == 200} {
				set data [string trim [http::data $token]]	;# trim is a must
				if [string equal {} $data] {
					if [info exists namespacePrefixXresolverURLarray($resolverID)] {unset namespacePrefixXresolverURLarray($resolverID)}
				} else {
					set namespacePrefixXresolverURLarray($resolverID) [list $data $seconds]	;# update namespacePrefixXresolverURLarray cache
				}
				StoreArray namespacePrefixXresolverURLarray $homePath/col/$URLibServiceRepository/auxdoc/namespacePrefixXresolverURLarray.tcl w list array 1
				file delete $homePath/col/$URLibServiceRepository/auxdoc/uriPrefixXresolverURLarray.tcl	;# migration uriPrefixXresolverURLarray.tcl -> namespacePrefixXresolverURLarray.tcl - 2025-10-14
			}
			http::cleanup $token
		}
# UPDATE - end
	} else {
# nothing to do
	}
}	
	ConditionalSet outputValue namespacePrefixXresolverURLarray($resolverID) {}
	set resolverURLlist [lindex $outputValue 0]
if 0 {	 	
	puts 
	puts --$resolverURLlist--
}
		
# 2 IBInamespacePrefixList
# automatic update of IBInamespacePrefixList
	if [file exists $homePath/col/$URLibServiceRepository/auxdoc/IBInamespacePrefixList.tcl] {
		source $homePath/col/$URLibServiceRepository/auxdoc/IBInamespacePrefixList.tcl	;# set IBInamespacePrefixList cache
	} else {
		set IBInamespacePrefixList {}
	}
# similar code in ComputeFileUpdateFlag
	set mtime [lindex [lsearch -index 0 -inline $IBInamespacePrefixList $resolverID] 1]
	if [string equal {} $mtime] {set mtime 0}
	if {[expr ($seconds - $startingSecond)/$timePeriod] != [expr ($mtime - $startingSecond)/$timePeriod]} {
# since the last update (mtime), at least one transition time has occured
# where the transition times is = {starting second + n * time period: n = 0, 1, ...}
# old array input value, the input value should be updated
# UPDATE
# see: Confirming the existence of a given namespace prefix for the IBI namespace
#		set url http://gjfb:1905/col/urlib.net/www/2025/09.20.21.06/doc/script.cgi?namespaceprefix=$resolverID
		set url http://urlib.net/col/urlib.net/www/2025/09.20.21.06/doc/script.cgi?namespaceprefix=$resolverID
		if [catch {http::geturl $url} token] {
# nothing to do		
		} else {
			if {[http::ncode $token] == 200} {
				set flag [http::data $token]
# puts --$flag--
				if $flag {
					lappend IBInamespacePrefixList [list $resolverID $seconds]
					set IBInamespacePrefixList [lsort -unique -index 0 $IBInamespacePrefixList]
				} else {
					set index [lsearch -index 0 $IBInamespacePrefixList $resolverID]
					set IBInamespacePrefixList [lreplace $IBInamespacePrefixList $index $index]
				}
				set fileContent "set IBInamespacePrefixList [list $IBInamespacePrefixList]"
				Store fileContent $homePath/col/$URLibServiceRepository/auxdoc/IBInamespacePrefixList.tcl
				file delete $homePath/col/$URLibServiceRepository/auxdoc/IBIuriPrefixList.tcl	;# migration IBIuriPrefixList.tcl -> IBInamespacePrefixList.tcl - 2025-10-14
			}
			http::cleanup $token
		}
# UPDATE - end
	} else {
# nothing to do
	}
	
	set i 1
	foreach resolverURL $resolverURLlist {
		if [string equal {} $resolverURL] {
			puts "Location: http://$ibiResolver/customizeerror.cgi/603"	;# must be after # 2 IBInamespacePrefixList to do replace
			puts ""
			return
		}
		
		if {[lsearch -index 0 $IBInamespacePrefixList $resolverID] != -1} {
# an IBI resolver
			if [string equal {-} [string index $resolverID end]] {
				set url $resolverURL/IBI-:$destination$queryString
			} else {
				set url $resolverURL/IBI:$destination$queryString
			}
			if {[llength $resolverURLlist] == $i} {
				puts "Location: $url"
				puts ""
				return
			} else {
				if [catch {http::geturl $url} token] {
# nothing to do		
				} else {
					if {[http::ncode $token] == 200} {
						set data [string trim [http::data $token]]	;# trim is a must
						if [regexp {identifier warning} $data] {
							http::cleanup $token
							continue
						} else {
							puts "Location: $url"
							puts ""
							return
						}
					}
					http::cleanup $token
				}
			}
		}
		incr i
	}
#	if [regexp {^ibi-?$} $resolverID] #	;# added by GJFB in 2023-11-11 to display a copy (if any) of the item identified by its doi - added by GJFB in 2025-06-29
	if {0 && [regexp {^ibi-?$} $resolverID]} {	;# added by GJFB in 2023-11-11 to display a copy (if any) of the item identified by its doi - added by GJFB in 2025-06-29
#		set link $localSite/$resolverID:$destination$queryString
		set url http://$localSite/$resolverID:$destination$queryString
	} elseif {[regexp {^(urn:doi|doi)$} $resolverID]} {	;# added by GJFB in 2023-11-11 to display a copy (if any) of the item identified by its doi - added by GJFB in 2025-06-29
# urn:doi or doi
		global serverAddress	;# used by SetFieldValue
#		source $homePath/col/$URLibServiceRepository/doc/utilities1.tcl
		source $homePath/col/$URLibServiceRepository/doc/utilitiesMirror.tcl
		source $homePath/col/$URLibServiceRepository/doc/cgi/mirrorfind-.tcl
# serverAddress
		set serverAddress [list $env(SERVER_NAME) $env(URLIB_PORT)]
		
		set resultList [FindMetadataRepositories "doi $destination" 0 {} {} no no 1]
if 0 {	 	
	puts {Content-Type: text/html}
	puts {}
	puts --$resultList--
}		
		if [string equal {} $resultList] {
# no copies of the item identified by its doi were found in the URLib collection
			set url $resolverURL/$destination$queryString	;# use doi
		} else {
# a copy was found
			if [catch {http::geturl http://doi.org/} token] {	;# if added by GJFB in 2025-06-29
# site not found - use the copy
				foreach {site rep-i} [lindex $resultList 0] {break}			
#				puts --$site--
#				puts --${rep-i}--
				SetFieldValue $site ${rep-i} identifier
#				puts --$identifier--
#				set link $namespacePrefixXresolverURLarray(upn:4CR88AP)/upn:4CR88AP:$identifier$queryString	;# use ibi copy
				set url http://urlib.net/ibi:$identifier$queryString	;# use ibi copy
			} else {
# use the original - added by GJFB in 2025-06-29
				http::cleanup $token
				set url $resolverURL/$destination$queryString	;# use doi
			}
		}		
	} else {
## upn:4CR88AP or upn:4CR88AP- or ibi or ibi- or ark or ...
# ark or ...
		set url $resolverURL/$resolverID:$destination$queryString
	}
if 0 {
# testing 'Example of robust hypertext and authentic data' (QABCDSTQQW/4AEFPDB)	when GetOptimizedListOfSites was executed using MultipleExecute
	if [file exists $homePath/fileFlag] {
#		set xWaitQueue 0; after 1000 {set xWaitQueue 1}; vwait xWaitQueue
		set xWaitQueue 0; after 2000 {set xWaitQueue 1}; vwait xWaitQueue	;# OK
	} else {
		set x x
		Store x $homePath/fileFlag
	}
}
	
# location http://doi.org/10.17487/RFC8141 gerado em solve
	puts "Location: $url"
	puts ""
# => Location: http://doi.org/10.1590/0001-3765202320210807?ibiurl.clientinformation.citingitem=urlib.net/www/2023/11.16.13.37&linktype=relative 
	} m] {
	if ![string equal {} $m] {
		puts {Content-Type: text/html}
		puts {}
		puts "Resolve: $m
"
		if 0 {global errorInfo; puts $errorInfo
}
	}
}
}
#