#!/usr/bin/env zsh
# -*- mode: sh; sh-indentation: 4; indent-tabs-mode: nil; sh-basic-offset: 4; -*-

# Copyright (c) 2020 Sebastian Gniazdowski

∧za-meta-plugins-before-load-handler() {

    # Set the base and typically useful options.
    builtin emulate -LR zsh
    builtin setopt extendedglob warncreateglobal typesetsilent noshortloops rcquotes

    local type=$1 id=$2 id_as=$3 args=$4 ices=$5 hook=$6 subtype=$7

    if (( $+ZINIT_ICE[debug] )) {
        # Enable the output from this annex
        integer ibshow_messages=1
    }

    # Exclude IDs with slashes and also packages
    [[ $id == */* ]] && local bad_id=1 
    [[ $id == *:* ]] && local bad_id2=1
    [[ $ZINIT_ICE[teleid] == */* ]] && local bad_tele=1
    (( $+ZINIT_ICE[pack] )) && local is_pack=1
    if (( bad_id || bad_id2 || bad_tele || is_pack )) {
        if (( ibshow_messages )) {
            local -a msgs
            msgs=( ${bad_id:+the ID contains a slash} ${bad_id2:+the ID looks like a snippet ID}
                   ${bad_tele:+"the {ice}teleid{meta}''{msg} ice contains a slash"}
                   ${is_pack:+"the ID is a package / {ice}pack{meta}''{msg} ice given"} )
            +zinit-message "{pre}meta-plugins annex: {msg}Skipping the ID: {meta2}$id{msg}" \
                "(reason(s): ${(j:, :)msgs}).{rst}"
        }
        return 0
    }

    integer ibshow_messages iberror_flag
    local -a match mbegin mend reply
    local MATCH REPLY
    integer MBEGIN MEND

    local -A tpe_map
    tpe_map=( 0 plugin 1 snippet )

    # Reset the communication fields.
    ZINIT[annex-before-load:new-@]=""
    ZINIT[annex-before-load:new-global-ices]=""

    # Strip the ID from some possible accidental /-s.
    id=${${id#@}%%(///|//|/)}

    local meta_plugin_data=${(v)Zinit_Annex_Meta_Plugins_Map[$id]}

    if [[ -n $meta_plugin_data ]] {
        # Count the recognized meta-plugins
        Zinit_Annex_Meta_Plugins_Map[recon-count]=$(( Zinit_Annex_Meta_Plugins_Map[recon-count] + 1 ))

        local -a plugin_array loaded_plugins not_existing
        plugin_array=( ${(s: :)meta_plugin_data} )
        loaded_plugins=( ${(@Q)${(@z)Zinit_Annex_Meta_Plugins[annex-loaded-plugins]}} )

        local p
        for p ( $plugin_array ) {
            if [[ -z $Zinit_Annex_Meta_Plugins_Map[$p] ]] && \
                ! .zinit-get-object-path AUTO $p
            then
                ibshow_messages=1
                not_existing+=( $p )
            fi
        }

        # Debug message.
        if (( ibshow_messages )) {
            (($+functions[.zinit-two-paths])) || builtin source $ZINIT[BIN_DIR]/zinit-side.zsh

            # Output a separating newline if the previous-processed
            # plugin isn't a meta-plugin → to cluster the messages.
            [[ -z $Zinit_Annex_Meta_Plugins_Map[${ZINIT[annex-exposed-processed-IDs]##* }] ]] && builtin print 

            +zinit-message -n "{hi}$Zinit_Annex_Meta_Plugins_Map[recon-count].{rst} "
            +zinit-message -n "{pre}[meta-plugins annex]{msg} Installing" \
                "{bold}{meta2}meta-plugin{ehi}: {rst}{msg}\`{meta}{bold}$id{rst}{msg}'" \
                "consisting of{ehi}:{rst}"
            integer count
            local -a skipped
            for p ( $plugin_array ) {
                count+=1
                .zinit-any-colorify-as-uspl2 $p
                [[ $p = $plugin_array[-1] ]] && local enotlast= || local enotlast=0
                REPLY=${REPLY//\//∕}

                if (( ${loaded_plugins[(I)$p]} && !${not_existing[(I)$p]} )) {
                    skipped+=( $REPLY )
                    REPLY="{dbg}$p {warn}a/l{rst}"
                }

                +zinit-message -n " {bold}$count{rst}{msg}) $REPLY{msg}${enotlast:+,}"
            }
            +zinit-message ".{rst}"
            if (( ibdebug && ${#skipped} )) {
                +zinit-message -n "{hi}$Zinit_Annex_Meta_Plugins_Map[recon-count].{rst} "
                +zinit-message "{pre}[meta-plugins annex]{msg} Skipping already" \
                    "loaded: ${(j:, :)skipped}{msg}.{rst}"
            }
        }

        # Pre-process each plugin retrieving the assigned, default
        # ice-lists and preparing the above communication fields.
        for p ( $plugin_array ) {
            local ice_list_data=$Zinit_Annex_Meta_Plugins_Config_Map[$p]
            if (( ! ${loaded_plugins[(I)$p]} || ${not_existing[(I)$p]} )) {
                ZINIT[annex-before-load:new-@]+="$ice_list_data @${(q)p} "
                Zinit_Annex_Meta_Plugins[annex-loaded-plugins]+=" ${(q)p}"
            }
        }
        ZINIT[annex-before-load:new-@]+=" $args"
    }

    return $(( ${${ZINIT[annex-before-load:new-global-ices]:+4}:-0} + \
            ${${ZINIT[annex-before-load:new-@]:+2}:-0} + iberror_flag ))
}

# vim:ft=zsh:tw=80:sw=4:sts=4:et
