#!/usr/bin/env bash

CI_LIB_DIR=/usr/bin/lib
# shellcheck disable=SC1091
source "${CI_LIB_DIR}/xivo-version.sh"
# shellcheck disable=SC1091
source "${CI_LIB_DIR}/printers.sh"
# shellcheck disable=SC1091
source "${CI_LIB_DIR}/helpers.sh"
# shellcheck disable=SC1091
source "${CI_LIB_DIR}/dry-run.sh"

usage() {
    cat <<EOF
Usage: xivo-tag-package <version.subversion> <tag_type> <branch> [--dry-run]

 - <version.subversion> mandatory, numeric version : 2017.03.02 for instance
 - <tag_type> mandatory, tag type : rc or prod

 - <branch> optionnal, branch where to create the tag, defaults to current branch
 - --dry-run optionnal, if provided will show you the steps without actually tagging.

 - -h, --help, will display this help if passed as first argument.
EOF
}

verify_git_project() {
    is_in_git_project=$(git rev-parse --is-inside-work-tree)
    if [ "${is_in_git_project}" != "true" ]; then
        cmn_echo_warn "Error : you must call this tool inside the git project of the package you want to tag"
        exit_abnormally
    fi
}

verify_tag_type() {
    if [ "$1" != "rc" ] && [ "$1" != "prod" ]; then
        cmn_echo_warn "Error : please provide a correct tag type : rc or prod"
        exit_abnormally
    fi
}

verify_changelog_head() {
    changelog_head=$(head -n 1 debian/changelog)
    changelog_correct=$(echo "$changelog_head" | grep "$1")
    if [ -z "$changelog_correct" ]; then
        cmn_echo_warn "Error: Changelog head is $changelog_head"
        cmn_echo_warn "You were expecting $1"
        cmn_echo_warn "Did you forget to update debian/changelog ?"
        exit_abnormally
    fi
}

verify_tag_doesnt_exist() {
    result=$(git tag -l "$1")
    if [ -n "$result" ]; then
        cmn_echo_warn "Warning: The tag is already set, exiting."
        exit 42
    fi
}

verify_rc_tag_does_exist() {
    result=$(git tag -l "$1")
    if [ -z "$result" ]; then
        cat <<EOF
Error: Production tags are based on rc tag
rc tag not found
You may want to rerun this script with rc
EOF
        exit_abnormally
    fi
}

main() {
    verify_help_asked "$1"
    verify_git_project
    if [ -z "$1" ]; then
        cmn_echo_warn "Error : please provide arguments."
        exit_abnormally
    fi
    numeric_version="$1"
    shift

    verify_numeric_version "$numeric_version"

    if [ -z "$1" ]; then
        cmn_echo_warn "Error : please provide a tag type : rc or prod"
        exit_abnormally
    fi
    tag_type="$1"
    shift
    verify_tag_type "$tag_type"

    if [ -n "$1" ]; then
        verify_dry_run "$1"
        if [ "$DRY_RUN" = true ]; then
            shift
        fi
    fi
    if [ -n "$1" ]; then
        branch_name="$1"
        shift
        git checkout "$branch_name" || exit_abnormally
    fi
    if [ -n "$1" ]; then
        verify_dry_run "$1"
        if [ "$DRY_RUN" = true ]; then
            shift
        else
            cmn_echo_warn "Additionnal parameter $1 unexpected. Exiting."
            exit_abnormally
        fi
    fi
    if [ "$DRY_RUN" = false ]; then
        cmn_echo_warn "dry run mode off, be careful"
    fi

    git pull

    verify_changelog_head "$numeric_version"

    rc_tag="$numeric_version"-rc
    if [ "$tag_type" == "rc" ]; then
        tag_to_write="$rc_tag"
        cmn_echo_important "Tagging in rc with $tag_to_write"
    else
        tag_to_write="$numeric_version"
        cmn_echo_important "Tagging in prod with $tag_to_write"
    fi
    verify_tag_doesnt_exist "$tag_to_write"
    if [ "$tag_type" == "rc" ]; then
        if [ "$DRY_RUN" = true ]; then
            echo_dry_run "git tag -a \"$tag_to_write\" -m \"$numeric_version Release candidate\""
        else
            git tag -a "$tag_to_write" -m "$numeric_version Release candidate"
        fi
    else
        verify_rc_tag_does_exist "$rc_tag"
        git config advice.nestedTag false #creating a tag on another generates a nested tag warning
        if [ "$DRY_RUN" = true ]; then
            echo_dry_run "git tag -a \"$tag_to_write\" -m \"$numeric_version Final Release\" \"$rc_tag\""
        else
            git tag -a "$tag_to_write" -m "$numeric_version Final Release" "$rc_tag"
        fi

    fi
    if [ "$DRY_RUN" = true ]; then
        echo_dry_run "git push -u origin \"$tag_to_write\""
    else
        git push -u origin "$tag_to_write"
    fi
    cmn_echo_important "Tag successful. Exiting"
    exit
}

main "${@}"
