#!/bin/bash
# SPDX-License-Identifier: GPL-2.0-only

#  (kgit), (mux and demux for kgit* tools)

#  Copyright (c) 2008-2016 Wind River Systems, Inc.

#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License version 2 as
#  published by the Free Software Foundation.

#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#  See the GNU General Public License for more details.

#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

mydir=`dirname $0`
PATH=$mydir:$PATH

# For consistent behaviour with "grep -w"
LC_ALL=C
export LC_ALL

usage()
{
cat <<EOF

 kgit -h --version <command>

   --meta  :  print the meta directory name
   -h      :  this message
   -v      :  version

EOF
}

meta_dir()
{
    # if there's already a located and logged meta directory, just use that and
    # return. Otherwise, we'll look around to see what we can find.
    if [ -f ".metadir" ]; then
        md=`cat .metadir`
        echo $md
        return
    fi

    # determine the meta directory name
    meta_dir_options=`git ls-files -o --directory`
    for m in $meta_dir_options; do
        if [ -d "$m/cfg" ]; then
            md=`echo $m | sed 's%/%%'`
        fi
    done

    # if nothing was found, we create the minimal structure
    if [ -z "$md" ]; then
        md=".kernel-meta"
    fi

    mkdir -p "${md}/cfg/scratch"

    # store our results where other scripts can quickly find the answer
    echo "${md}" > .metadir
    # return the directory to he caller
    echo $md
}

_commands()
{
    find "`dirname $0`" -maxdepth 1 -name "kgit-*" -type f \
                  -perm -111 | sed -e "s/.*\\/`basename $0`-//"
}

# take the entire command into an array
raw_command=($@)

# are we being sourced ?
script_name=$( basename $0 )
this_script=$( basename ${BASH_SOURCE} )
if [[ ${script_name} = ${this_script} ]] ; then
    sourced=
else
    sourced=t
fi

if [ -z "${sourced}" ]; then
    non_dashed=""
    while [ $# -gt 0 ]; do
        case "$1" in
            -v) verbose=t
                ;;
            --meta)
                if [ -z "${non_dashed}" ]; then
                    meta=t
                    meta_dir
                    exit 0
                fi
                ;;
            -h|--help)
                if [ -z "${non_dashed}" ]; then
                    usage
                    exit
                fi
                ;;
            --*)
                # if the next argument is dashed, we just add $1 to our collection
                # of dashed arguments. If $2 is NOT dashed, we assume it is a parameter
                # to the --dashed option, and we grab it as well. Don't try and mix
                # dashed and non-dashed, since we'll grab them!
                case $2 in
                    --*)
                        dashed="${dashed} $1"
                        ;;
                    *)
                        # sneak a : in between, so we can split it later
                        dashed="${dashed} $1:$2"
                        shift
                        ;;
                esac
                ;;
            *) non_dashed="${non_dashed} $1"
               ;;
        esac
        shift
    done

    # based off guilt's demux and other references
    if [ "`basename $0`" = "kgit" ]; then
        # make an array from whatever was non-dashed
        cmd_options_non_dashed=(${non_dashed})

        cmd=
        if [ ${#cmd_options_non_dashed[@]} -ne 0 ]; then
            # take first arg, and try to execute it
            arg="${cmd_options_non_dashed[0]}"
            dir=`dirname $0`

            if [ -x "$dir/kgit-$arg" ]; then
                cmd=$arg
            else
                # might be a short handed
                for command in $(_commands); do
                    case $command in
                        $arg*)
                            if [ -x "$dir/kgit-$command" ]; then
                                cmd=$command
                            fi
                            ;;
                    esac
                done
            fi
            if [ -n "$cmd" ]; then
                # remove the first element, since that is our command. The rest are what
                # we pass to the sub command.
                sub_cmd_options=("${raw_command[@]:1}")
                exec "$dir/kgit-$cmd" "${sub_cmd_options[@]}"

                # this is not reached because of the exec
                die "Exec failed! Something is terribly wrong!"
            fi
        fi

        # no args passed or invalid command entered, just output help summary
        usage
        echo " Available commands: "
        echo ""
        echo -n "    "
        count=0
        for c in $(_commands); do
            if [ $count -lt 7 ]; then
                echo -n "$c "
            else
                echo "$c"
                count=0
                echo -n "    "
            fi
            let count=$count+1
        done
        echo ""; echo ""

        # now, let's exit
        exit 1
    fi
fi


get_current_git_branch()
{
    git branch --no-color | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'
}   

strlen ()		# echo ${#string} ...
{
    for i in "$@"; do
        echo ${#i}
    done
}

# arg1: length limit
# arg2: string
length_limited_string()
{
    limit=$1
    input_string=$2

    mid_point=`expr length $input_string / 2`
    mid_point=`expr $mid_point - 5`

    # limit_point=`expr length $limit / 2`
    # len=`expr length $input_string`
    # if [ `expr $limit_point+$limit_point < $len` ]; then
    #    echo "why bother ?"
    # fi

    x=${input_string:0:$mid_point}
    y=${input_string: -$mid_point}

    echo "$x..$y"
}

find_dir()
{
    start_dir=`pwd`
    done=0
    count=0
    tgt_dir="$1"
    max_depth=$2

    if [ -z "$max_depth" ]; then
	max_depth=4
    fi

    cdir=".";
    while [ $done -eq 0 ]; do
        # echo "testing: $start_dir/$cdir/tgt_dir"
        if [ -d "$start_dir/$cdir/$tgt_dir" ]; then
            done=1;
        else
            # echo "not found, heading back one ...";
            cdir="../$cdir";
            let count=$count+1;
            # echo "count: $count";
        fi;

        if [ $count -gt $max_depth ]; then
            cdir="";
            done=1;
        fi;
    done

    if [ "$cdir" != "" ]; then\
        cdir=`echo $cdir | sed "s/\.\///"`;
        echo "$cdir/$tgt_dir";
    fi
}

read_answer()
{
    prompt=$1
    default_answer=$2

    answer="$default_answer"
    echo -n "    $prompt [$default_answer]: "
    read answer

    echo $answer
}

clean_path()
{
    _p=$1

    _p=`echo $_p | sed 's%//%/%g' | sed 's%\\.\/%%g'`

    # double check our efforts
    while :
    do
	case $_p in
	    # disable the check for trailing slash and removal. We want this
	    # to be present, and we really only care about double //
	    #*/) _p=${_p%/} 
	    #	;;

	    *//*) _p=`echo $_p | sed s%//%/%g` 
                ;;

	    *) break
		;;
	esac
    done

    echo $_p
}

clean_repo()
{
    if [ -n "$verbose" ]; then
	echo "[INFO] cleaning base clone"
    fi

    if [ -d .git ]; then
	# Keep tags that came from kernel.org; delete the rest, i.e.
	# v3.nn, v2.6.nn and v2.6.nn-rcM and v2.6.nn.M (nn=10,11, ..99, M=0,1, ...99)
	for tg in `git tag| grep -v 'v2.6.[0-9]\{2\}\(\(-rc[0-9]\{1,2\}\)\{0,1\}$\|\.[0-9]\{1,2\}$\)' |
                            grep -v 'v3.[0-9]\{2\}\(\(-rc[0-9]\{1,2\}\)\{0,1\}$\|\.[0-9]\{1,2\}$\)' |
                            grep -v 'v4.[0-9]\{2\}\(\(-rc[0-9]\{1,2\}\)\{0,1\}$\|\.[0-9]\{1,2\}$\)'`
	do
	    git tag -d $tg > /dev/null
	done

	# We've come here without an active checkout, on what was a bare
	# clone, so manually make sure we are on master. We should be on
	# master anyway, but make sure, otherwise we won't be able to
	# delete whatever branch we are on.
	echo 'ref: refs/heads/master' > .git/HEAD
	for br in `git branch | grep -v '\* master$'`
	do
	    git branch -D $br > /dev/null
	    if [ $? != 0 ]; then
		echo "[ERROR]: delete of branch $br failed"
		exit -1
	    fi
	done
    fi
}