#!/bin/sh
#
#  Author: Vlad Seryakov vseryakov@gmail.com
#  Sep 2013
#

case "$BKJS_CMD" in

  help|bundle-help)
    echo
    echo "  bundle [-file FILE|(js|css|html)|BUNDLE.(js|css|html)] [-dir D] [-dirs DIRS...] [-find DIRS...] [-gzip] [-dev DEV] [-uglifyargs ARGS] [-all] [-force] [-clean] - produce a web bundle by uglifying js/css/html files into one file, resolves files from package.json"
    ;;

  bundle)
    # Rebuild all inside of the specified folders
    dirs=$(get_arg -dirs)
    if [[ -z "$dirs" ]]; then
        dirs=$(get_arg -find)
        depth=$(get_arg -depth 1)
        [[ -n "$dirs" ]] && dirs=$(find $dirs -maxdepth $depth -mindepth 1 -type d)
    fi
    if [[ -n "$dirs" ]]; then
        skip=$(get_arg -skip)
        filter=$(get_arg -filter)
        args=$(get_all_args "-dirs -find -skip -filter")
        debug dirs: $dirs, args: $args
        for dir in $dirs; do
            if match $dir $skip; then continue; fi
            if [ -n "$filter" ] && match $dir $filter; then continue; fi
            $BKJS_BIN $BKJS_CMD -dir $dir $args
            [ "$?" != "0" ] && msg "dir $dir failed" && exit 1
        done
        exit 0
    fi

    gzip=$(get_flag -gzip)

    # Rebuild all bundles
    if [[ -n "$(get_flag -all)" ]]; then
        dir=$(get_arg -dir)
        if [ "$dir" != "" ]; then
            cd $dir
            [ "$?" != "0" ] && exit 1
        fi

        [ -f package.json ] && bundles=$(get_json_flat package.json config.bundles)

        debug all: $bundles

        for b in $bundles; do
            for t in css js; do
                $BKJS_BIN $BKJS_CMD -file $b.$t $(get_all_args "-all -file")
                [ "$?" != "0" ] && msg "bundle $b failed" && exit 1
            done
        done

        if [ -n "$gzip" ]; then
            for f in $(find web -name '*.min.js' -or -name '*.min.css'); do
                gzip -9 -c $f > $f.gz
            done
        fi
        exit 0
    fi

    # Delete all bundles
    if [[ -n "$(get_flag -clean)" ]]; then
        rm -f web/css/*.bundle.css* web/css/*.min.css.gz web/js/*.bundle.*js* web/js/*.min.js.gz
        exit 0
    fi

    file=$(get_arg -file)
    [ "$file" = "" ] && echo "-file must be provided, args: $@" && exit 1
    quiet=$(get_flag -quiet)
    force=$(get_flag -force)
    dev=$(get_arg -dev)
    fopts=$(get_arg -fopts)

    # Default or named dev bundle
    [ "$dev" = "" ] && dev=$(get_flag -dev)
    [ "$dev" = "1" ] && dev=dev

    if match $file "\.bundle\.(js|css|html)$"; then
       exit
    elif match $file "^([a-zA-Z0-9\._-]+)?(js|css|html)$"; then
       dir=$(pwd)
       type=${file##*.}
       name=${file%.*}
    else
       dir=$(dirname $file)
       while ! [ -e "$dir/package.json" ] && [ -n "$dir" ] && [ "$dir" != "." ]; do
           dir=${dir%/*}
           [ "$dir" = "$_dir" ] && break
           _dir=$dir
       done
       base=$(echo $file|sed "s|$dir/||")
       type=${base##*.}
       name=${base%.*}
       fopts="$fopts realpath"
    fi
    if [ ! -f $dir/package.json ]; then
       msg "package.json is not found"
       exit 1
    fi
    [ "$type" = "html" ] && type=js
    repo=$(cd $dir && git symbolic-ref --short -q HEAD 2>/dev/null)

    [ -f $dir/package.json ] && bundles=$(get_json_flat $dir/package.json config.bundles)

    [ "$quiet" = "" ] && msg "$repo: $dir: $name.$type.$dev FILE: $file BUNDLES: $bundles"

    for b in $bundles; do
        unset sources
        cd $dir
        [ "$?" != "0" ] && exit 1
        if [[ -n "$dev" ]]; then
            sources=$(get_json_flat package.json config.bundles.$b.$type.$dev "" "$fopts")
            [ "$?" != "0" ] && exit 1
        fi
        if [[ -z "$sources" ]]; then
            sources=$(get_json_flat package.json config.bundles.$b.$type "" "$fopts")
            [ "$?" != "0" ] && exit 1
        fi
        debug $b.$type.$dev: $fopts FILES: $sources

        [[ -z "$sources" ]] && continue

        if [[ -z "$name" || $name = $b ]] || match "$sources" $file; then
            files=$sources
            bundle=$b

            debug $bundle.$type: started $dir/$file, files: $files

            case $file in
            *.js|*.html)
                mkdir -p $dir/web/js
                echo "" > $dir/web/js/$bundle.bundle.js
                jsfiles=""
                for f in $files; do
                    [ ! -s $f ] && msg "$bundle.$type: $f not found" && exit 1

                    debug $bundle.$type: $f

                    case $f in
                    *.min.js)
                        cat $f >> $dir/web/js/$bundle.bundle.js
                        ;;

                    *.js)
                        if [[ -z "$dev" ]]; then
                            jsfiles="$jsfiles $f"
                        else
                            cat $f >> $dir/web/js/$bundle.bundle.js
                        fi
                        ;;

                    *.html)
                        n=$(basename $f .html)
                        echo "app.templates[\"$n\"]='$(cat $f|tr -d '\r\n'|sed "s/['\\]/\\\&/g")';" >> $dir/web/js/$bundle.bundle.js
                        ;;
                    esac
                done

                if [ -z "$dev" ]; then
                    if [ -n "$jsfiles" ]; then
                        if [ -n "$(get_flag -esbuild)" ]; then
                            esbuildargs="--minify $(get_arg -esbuildargs)"
                            esbuild $esbuildargs $jsfiles >> $dir/web/js/$bundle.bundle.js
                            [ "$?" != "0" ] && exit 1
                        else
                            uglifyargs="-c -m --comments /^!/ $(get_arg -uglifyargs)"
                            uglifyjs $jsfiles $uglifyargs >> $dir/web/js/$bundle.bundle.js
                            [ "$?" != "0" ] && exit 1
                        fi
                    fi
                    [ -n "$gzip" ] && gzip -9 -c $dir/web/js/$bundle.bundle.js > $dir/web/js/$bundle.bundle.js.gz
                fi
                ;;

            *.css)
                mkdir -p $dir/web/css
                (cd $dir && cat $files > web/css/$bundle.bundle.css)
                [ "$?" != "0" ] && exit 1
                if [ -z "$dev" ]; then
                    [ -n "$gzip" ] && gzip -9 -c $dir/web/css/$bundle.bundle.css > $dir/web/css/$bundle.bundle.css.gz
                fi
                ;;
            esac

            debug $dir/web/$type/$bundle.bundle.$type finished
        fi
    done
    [ -z "$files" ] && debug no $type config.bundles found in $dir/package.json

    exit 0
    ;;

esac
