# -*- mode: sh; sh-indentation: 4; sh-basic-offset: 4; indent-tabs-mode: nil;  -*-

# Copyright 2020 Sebastian Gniazdowski
# License: MIT

# Synopsis:
#   zinit shim-list [-t|--this-dir] [-c|--cat] [-i|--from-ices] \
#		    [-o|--one-line] [-s|--short]
#

za-bgn-shim-list() {

emulate -LR zsh
setopt extended_glob warn_create_global typeset_silent \
        no_short_loops rc_quotes

autoload is-at-least
local is_58
is-at-least 5.8 && is_58=1

local -a opt_help opt_this_dir opt_cat opt_from_ices opt_one_line \
	opt_short
zparseopts -D -E ${is_58:+-F} \
	      h=opt_help -help=opt_help \
	      t=opt_this_dir -this-dir=opt_this_dir \
	      c=opt_cat -cat=opt_cat \
	      i=opt_from_ices -from-ices=opt_from_ices \
	      s=opt_short -short=opt_short \
	      o=opt_one_line -one-line=opt_one_line || \
		{ 
		  print -Pr "$ZINIT[col-error]Error:$ZINIT[col-msg2]" \
		    "Incorrect options given to" \
		    "$ZINIT[col-obj]shim-list$ZINIT[col-msg2], try" \
		    "$ZINIT[col-obj]--help%f"
		  return 1
		}

(( ${#opt_help} )) && {
    print -P "$ZINIT[col-obj]Usage:%f\n" \
	"zinit shim-list [-h/--help] [-t|--this-dir] [-i|--from-ices] \\\\\n" \
 	"    [-o|--one-line] [-s|--short] [-c|--cat]"
    cat <<END

- -h/--help	 – shows this message,
- -t/--this-dir  – instructs Zinit to look for shims in the current
		   directory instead of $ZPFX/bin,
- -i/--from-ices – normally the code looks for the shim files by examining
		   their contents (shims created by BGN annex have a fixed
		   structure); this option instructs Zinit to show the list of
		   shims that results from the sbin'' ice of the loaded
		   plugins; i.e.: if a plugin has sbin'git-open', for example,
		   then this means that there has to be such shim already
		   created,
- -o/--one-line  – display the list of shim files without line breaks, in
		   single line, after spaces,
- -s/--short     – don't show the plugin/snippet that the shim belongs to,
- -c/--cat       – displays contents of each of the found shim
		   (unimplemented yet).
END
    return 0
}

(( !${+functions[.zinit-any-colorify-as-uspl2]} )) && \
    builtin source $ZINIT[BIN_DIR]/zinit-side.zsh

# To `cat`… or `pr`…:
{

    if (( !${#opt_from_ices} )) {
	local nl=$'\n' brace='{' quote='"'
	local pattern='(#s)\#!/usr/bin/env zsh

    function * {
	local bindir="'

	local -a cands
	cands=( ${${opt_this_dir:+.}:-$ZPFX/bin}/*(.-NDL-1000) )
	cands=( ${cands:#.} )

	local rempat="(${ZINIT[PLUGINS_DIR]}|${ZINIT[SNIPPETS_DIR]}"
	rempat+="|${ZINIT[PLUGINS_DIR]/.zinit/.zplugin}"
	rempat+="|${ZINIT[SNIPPETS_DIR]/.zinit/.zplugin})"
	local snippat="(${ZINIT[SNIPPETS_DIR]}|${ZINIT[SNIPPETS_DIR]/.zinit/.zplugin})/*"

	local file
	local -a found
	integer longest len
	for file ( $cands ) {
	    local body="$(<$file)"
	    if [[ -n ${body[(r)$pattern]} ]] {
		len=${#${file:t}}
		(( len > longest )) && longest=len
		found+=( $file )
	    }
	}

	for file ( $found ) {
	    local body="$(<$file)" name=$file:t
	    print -r ${${:-$opt_one_line${(M)${opt_short:-1}:#1}}:+-n} -- ${file:t}" " \
		${${(M)${opt_short:-1}:#1}:+${(l:longest+1-${#name}:: :):-}}

	    if (( !${#opt_short} )) {
		if [[ $body = (#b)$~pattern([^$nl]##)$nl* ]] {
		    local pth=${match[1]%\"}
		    local id_as=${${${pth##$~rempat}##/##}%\"}
		    if [[ $pth = $~snippat ]] {
			if [[ $id_as = ((OMZ|PZT|PZTM|OMZP|OMZT|OMZL)::|(#i)(http(s|)|ftp(s|)|rsync|ssh)--)* ]] {
			    { local url="$(<$pth/._zinit/url)" } 2>/dev/null
			} else {
			    local -A map
			    map=( -- "/" -EQ- "=" -QM- "?" -AMP- "&" )
			    local url=${id_as//(#m)(${(~j:|:k)map})/${map[$MATCH]}}
			}
			print -r "$ZINIT[col-obj]$url$ZINIT[col-rst]"
		    } else {
			(( ${+functions[.zinit-first]} )) || builtin source "${ZINIT[BIN_DIR]}/zinit-side.zsh"
			.zinit-any-colorify-as-uspl2 "$id_as"
			print -r -- "$REPLY"
		    }
		}
	    }
	}
	(( ${#opt_one_line} )) && print

    } else {
	+zinit-message '[msg2]Listing shims basing on the in-memory ices data...[rst]'
	local p
	local -A ices
	for p ( $ZINIT_REGISTERED_PLUGINS ) {
	    if [[ -n $ZINIT_SICE[$p] ]] {
		ices=( "${(@Q)${(@z)ZINIT_SICE[$p]}}" )
		local sbin
		local -a sbins
		sbins=( ${(s.;.)ices[sbin]} )
		if (( ${#sbins} )) {
		    .zinit-any-colorify-as-uspl2 "$p"
		}
		for sbin ( $sbins ) {
		    print "${(r:50:: :)sbin} $REPLY"
		}
	    }
	}
    }

} | if (( !${#opt_short} || ${#opt_one_line} )) {
	cat
    } else {
	pr -4 -T
    }
}

# vim:ft=zsh:sw=4:sts=4:noet:
