# VCS abstraction layer

. $LIB/pvl/commit/git.sh
. $LIB/pvl/commit/hg.sh

commit_GETOPTS='cCm:M'

COMMIT=
COMMIT_DIFF=
COMMIT_MSG=' '

function commit_help {
    cat <<END
Commit:
    -C      do not commit changes
    -c      commit changes
    -m MSG  commit message
    -M      interactive commit message
END
}

function commit_opt {
    local opt=$1
    local optarg="$2"

    case $opt in
        c)  COMMIT=1 ;;
        C)  COMMIT=0 ;;

        m)  COMMIT_MSG="$optarg" ;;
        M)  COMMIT_MSG= ;;
        
        n)  COMMIT=0 ;;
        p)  COMMIT_DIFF=1 ;;
        *)  return 1
    esac
}

function commit_probe {
    local repo="$1"

    for commit in git hg; do
        if ${commit}_probe "$repo"; then
            echo $commit
            return 0
        fi
    done

    return 1
}

## Commit changes to version control:
#
#   update_commit .../etc "commit message"
#
# Invokes `hg commit`, first showing the diff.
function commit {
    local repo="$1"
    local commit_msg="$COMMIT_MSG"

    # detect
    local commit="$(commit_probe "$repo")"

    if [ -z "$commit" ]; then
        log_warn "$repo: Unable to detect VCS repo"
        return 1
    fi

    # operate?
    if [ "$COMMIT" = 1 ]; then
        log_force "$repo: force commit"

        [ "$COMMIT_DIFF" ] && cmd_indent "    " ${commit}_diff "$repo" || true

        ${commit}_commit "$repo" "$commit_msg"

    elif ! ${commit}_modified "$repo"; then
        log_skip "$repo: no changes to commit"

    elif [ "$COMMIT" = 0 ]; then
        log_noop "$repo: skip commit"
        
        # still show diff, though
        [ "$COMMIT_DIFF" ] && cmd_indent "    " ${commit}_diff "$repo" || true
    else
        log_apply "$repo: commit: $commit_msg"

        [ "$COMMIT_DIFF" ] && cmd_indent "    " ${commit}_diff "$repo" || true

        ${commit}_commit "$repo" "$commit_msg"
    fi
}

function _commit {
    local repo="$1"
    local cmd="$2"

    # detect
    local commit="$(commit_probe "$repo")"

    if [ -z "$commit" ]; then
        log_warn "$repo: Unable to detect VCS repo"
        return 1
    fi
    
    ${commit}_${cmd} $repo "${@:3}"
}

function commit_modified {
    local repo="$1"

    _commit $repo modified
}

function commit_time {
    local repo="$1"

    _commit $repo time
}
