


___x_cmd_rule_ls(){
    [ $# -gt 0 ]    ||  set -- --help

    local ruleset_dir=""
    local format="yml"
    local x_=""

    while [ $# -gt 0 ]; do
        case "$1" in
            -h|--help)  ___x_cmd help -m rule ls "$@" ; return 0 ;;
            -r)         ruleset_dir="$2" ;  ___x_cmd_rule_ruleset_check_ "$ruleset_dir" || return $? ; arg:2:shift ;;
            --yml)      format="yml" ;      shift ;;
            --json)     format="json" ;     shift ;;
            --tsv)      format="tsv" ;      shift ;;
            --csv)      format="csv" ;      shift ;;
            :*)         [ -n "$ruleset_dir" ] || {
                            x_=""
                            ___x_cmd_rule_preset_resolve_ "$1" || N=rule M="Preset '$1' not found" log:ret:64
                            ruleset_dir="$x_"
                        }
                        shift ;;
            *)          break ;;
        esac
    done

    [ -n "$ruleset_dir" ] || {
        x_=""
        ___x_cmd_rule_which_ || N=rule M="Fail to locate any ruleset. You can use -r to specify" log:ret:64
        ruleset_dir="$x_"
    }

    ___x_cmd_rule_ls___"$format" "$ruleset_dir"
}

___x_cmd_rule_ls___yml(){
    local dir="$1"

    # If given a file (not directory), output it directly
    if [ -f "$dir" ]; then
        printf "## %s\n" "$dir"
        ___x_cmd rat "$dir"
        return 0
    fi

    local PWD=""
    local OLDPWD=""
    local x_=""
    local f=""
    ___x_cmd_cmds_cd "$dir"

    ___x_cmd fsiter --glob_ . '*.rule.yml'

    while read -r f; do
        printf "## %s\n" "$f"
        ___x_cmd rat "$f"
    done <<A
$x_
A

}

___x_cmd_rule_ls___json(){
    ___x_cmd_rule_ls___yml "$@" | ___x_cmd y2j
}

___x_cmd_rule_ls___tsv(){
    ___x_cmd_rule_ls___yml "$@" | ___x_cmd_rule_ls___flat tsv
}

___x_cmd_rule_ls___csv(){
    ___x_cmd_rule_ls___yml "$@" | ___x_cmd_rule_ls___flat csv
}

___x_cmd_rule_ls___flat(){
    local sep="$1"
    local delim=$'\t'
    [ "$sep" = csv ] && delim=','
    printf "id%sname%slevel%sfile\n" "$delim" "$delim"
}
