#!/usr/bin/env bash
SUCCESS_PROJECTS=()
PRETAGGED_PROJECTS=()
ERROR_PROJECTS=()

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-multi-tag <tag_type> <version.subversion> <repository_url_prefix> [--dry-run] <packager1>,<packager2> ...
 - <tag_type> mandatory : specifies the tag type, eg. rc or prod

 - <version.subversion> mandatory, numeric version : 2017.03.02 for instance
 
 - <repository_url_prefix> optionnal, repository url prefix to clone from (like git@gitlab.com:xivo.solutions)

 - --dry-run optionnal, if provided will show you the steps without actually tagging.

 - <packager1>,<packager2> mandatory : the list of packager projects to tag with that version. Should start with xivo

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

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
}

remove_packager() {
    packager_project=$1
    if [[ "$packager_project" = "" || "$packager_project" = "*" || "$packager_project" = "/" ]]; then
        cmn_echo_warn "Can't remove such project : $packager_project"
        exit_abnormally
    fi
    if [[ -e "$packager_project" ]]; then
        cmn_echo_important "Removing packager project $packager_project"
        rm -rf "${packager_project:?}"
    fi
}

assert_not_called_on_root() {
    if [[ "$PWD" = "" || "$PWD" = "*" || "$PWD" = "/" ]]; then
        cmn_echo_warn "You called this script here : $PWD"
        cmn_echo_warn "It is too dangerous to call this script on root folder, exiting"
        exit_abnormally
    fi
}

assert_packager_does_not_contain_invalid_characters() {
    packager_project=$1
    if [[ $packager_project = *[/~.]* ]]; then
        cmn_echo_warn "Packager $packager_project name contains /, ~, or ."
        cmn_echo_warn "This is not allowed, exiting."
        exit_abnormally
    fi
}

main() {
    assert_not_called_on_root
    verify_help_asked "$1"
    tag_type="$1"
    shift
    verify_tag_type "$tag_type"
    version="$1"
    shift
    verify_version "${version}"
    major_version=$(echo "${version}" | grep -o '^.\{0,7\}')
    set_branch "${major_version}"

    if [[ "${version}" = "${major_version}" ]]; then
        numeric_version="${major_version}.00"
    else
        verify_numeric_version "${version}"
        numeric_version=$(echo "${version}" | grep -o '^.\{0,10\}')
    fi
    cmn_echo_info "Each packager project will be tagged on branch $BRANCH with version ${numeric_version}"
    cmn_assert_command_is_available "xivo-tag-package"

    if [[ "$1" == "git@gitlab.com:"* ]]; then
        repository_url_prefix="$1"
        if [[ "$repository_url_prefix" != */ ]]; then
            repository_url_prefix="$1/"
        fi
        shift
    else
        repository_url_prefix="git@gitlab.com:xivo.solutions/"
    fi

    packages="$1"
    shift
    verify_dry_run "$packages"
    if [ "$DRY_RUN" = true ]; then
        packages="$1"
        shift
    fi
    declare -a package_list
    IFS=','
    read -ra package_list <<<"$packages"

    for packager_project in "${package_list[@]}"; do
        echo " "
        cmn_echo_important "You are about to tag project ${packager_project}
        on branch ${BRANCH}
        with type ${tag_type}
        with version ${numeric_version}
        from repo ${repository_url_prefix}${packager_project}.git"
        assert_packager_does_not_contain_invalid_characters "$packager_project"
        if [[ ! -d "${packager_project}" ]]; then
            git clone "${repository_url_prefix}${packager_project}.git" || ERROR_PROJECTS+=("$packager_project")
        fi
        if [[ -d "${packager_project}" ]]; then
            # shellcheck disable=SC2164
            cd "${packager_project}"
            git pull
            if [ "$DRY_RUN" = true ]; then
                xivo-tag-package "${numeric_version}" "${tag_type}" "${BRANCH}" --dry-run
                TAG_STATUS=$?
            else
                xivo-tag-package "${numeric_version}" "${tag_type}" "${BRANCH}"
                TAG_STATUS=$?
            fi
            if [ "$TAG_STATUS" == "0" ]; then
                SUCCESS_PROJECTS+=("$packager_project")
            else
                if [ "$TAG_STATUS" == "42" ]; then
                    PRETAGGED_PROJECTS+=("$packager_project")
                else
                    ERROR_PROJECTS+=("$packager_project")
                fi
            fi
            # shellcheck disable=SC2103
            cd ..
            remove_packager "$packager_project"
        fi
        echo " "
    done
    if [ "$DRY_RUN" = true ]; then
        cmn_echo_important "Congratulations ! Multi-tagging simulated."
    else
        cmn_echo_important "Congratulations ! Multi-tagging done for real."
    fi
    cmn_echo_info "These projects have been tagged successfully: ${SUCCESS_PROJECTS[*]}"
    cmn_echo_important "These projects were already tagged: ${PRETAGGED_PROJECTS[*]}"
    cmn_echo_warn "These projects have encountered issues while tagging: ${ERROR_PROJECTS[*]}"
}

main "$@"
