#! /bin/env tclsh

#package require {ycl exec}
#namespace import [yclprefix]::exec::pexec
package require {ycl list}
namespace import [yclprefix]::list::all
package require {ycl proc}
namespace import [yclprefix]::proc::checkargs
namespace import [yclprefix]::proc::checkspec
namespace import [yclprefix]::proc::dproc
package require {ycl ns}
namespace import [yclprefix]::ns
namespace import [yclprefix]::ns::object

package require {ycl crypto sha tcllibc} 
package require {ycl crypto sha openssl} 

variable doc::sha_coreutils
proc sha_coreutils {name args} {
}


variable doc::sha_tcllib
proc sha_tcllib {name args} {
}

variable doc::provision {
	description {
		Automatically provision an sha command.
	}
	args {
		name {
			description {
				Name of the command to create.
			}
		}
		accept {
			description {

				which providers to accept

				values

					auto

						automatically choose provider
							
							openssl

							tcllibc
					
					openssl

					tcllibc

			}
			default {
				lindex auto 
			}
			constrain {
				[all $accept in $providers]
				|| $accept eq {auto}
			}
		}
	}
	extra args2
}
checkspec $doc::provision

proc provision {name args} {
	variable providers
	set args2 {}
	checkargs [set doc::[namespace tail [lindex [info level 0] 0]]] {*}$args
	set name [ns normalize $name [uplevel namespace current]]
	set auto [lsearch $accept auto]
	if {$auto >= 0} {
		set accept [
			lreplace $accept[set accept {}] $auto $auto {*}$providers]
	}
	set errors {}
	foreach providername $accept {
		switch $providername {
			openssl - tcllibc {
				try {
					[$providername .spawn $name] init {*}$args2
				} on ok {} {
					break
				} on error {tres topts} {
					try {namespace delete $name} on error {} {}
					lappend errors [list $providername $tres $topts]
				}
			}
		}
	}
	if {[namespace which $name] eq {}} {
		return -code error $errors
	}
	#in order of performance, robustness, and ubiquity
	return $name
}

variable providers { 
	coreutils
	openssl
	perl
	SunOSDigest
	tcllib
	tcllibc 
	tcllibtcl
}
