#!/bin/bash
# SPDX-FileCopyrightText: Copyright (c) 2025 Yegor Bugayenko
# SPDX-License-Identifier: MIT

set -e -o pipefail

# shellcheck disable=SC1091
# Imported from commons.sh when releasing:
#!/bin/bash
# SPDX-FileCopyrightText: Copyright (c) 2025 Yegor Bugayenko
# SPDX-License-Identifier: MIT

set -e -o pipefail

if [ -n "${GITTED_TESTING}" ]; then
    set -x
fi

if [ -n "${GITTED_VERBOSE}" ]; then
    set -x
fi

function title_it {
    printf '\n👉 \e[1m%s\e[0m...\n' "$@"
}

function warn_it {
    printf '\n⚠️ \e[38;5;160m%s\e[0m\n' "$@"
}

function fail_it {
    warn_it "$@"
    exit 1
}

function bash_it {
    printf '%q ' "$@" | /bin/bash -x
}

function plural {
    printf "%s %s" "$1" "$2"
    if [ "$1" != '1' ]; then
        printf 's'
    fi
}

function retry_it {
    local message="$1"
    local cmd="$2"
    local max="${3:-10}"
    local attempt=1
    while (( attempt <= max )); do
        title_it "${message} (attempt no.${attempt}/${max})"
        eval "$cmd" && return 0
        if [ -n "${GITTED_TESTING}" ]; then
            exit 1
        fi
        attempt=$(( attempt + 1 ))
        sleep 1
    done
    fail_it "Command failed after ${max} attempts: ${cmd}"
}

base=$(dirname "$0")
export base

branches="$(git branch --format='%(refname:short)')"
if [ -z "${branches}" ]; then
    master="$(git symbolic-ref --short HEAD 2>/dev/null || exit 1)"
elif echo "$branches" | grep -qx 'master'; then
    master=master
elif echo "$branches" | grep -qx 'main'; then
    master=main
else
    fail_it "Neither 'master' nor 'main' branch found."
fi
export master

if [ -z "${GIT_BIN}" ]; then
    GIT_BIN=git
    export GIT_BIN
fi
# Imported from sanity.sh when releasing:
#!/bin/bash
# SPDX-FileCopyrightText: Copyright (c) 2025 Yegor Bugayenko
# SPDX-License-Identifier: MIT

set -e -o pipefail

GITTED_GIT_MIN_MAJOR=2
GITTED_GIT_MIN_MINOR=13

function gitted_sanity_fail {
    printf '\n⚠️ \e[38;5;160m%s\e[0m\n' "$@" >&2
    exit 1
}

GIT_BIN="${GIT_BIN:-git}"

if ! command -v "${GIT_BIN}" > /dev/null 2>&1; then
    gitted_sanity_fail "Git is not installed: '${GIT_BIN}' command was not found in PATH"
fi

gitted_git_version_raw=$("${GIT_BIN}" --version 2>/dev/null | awk '{print $3}')
if [ -z "${gitted_git_version_raw}" ]; then
    gitted_sanity_fail "Failed to detect Git version (could not parse output of '${GIT_BIN} --version')"
fi
IFS='.' read -r gitted_git_major gitted_git_minor _ <<< "${gitted_git_version_raw}"
if ! [[ "${gitted_git_major}" =~ ^[0-9]+$ ]] || ! [[ "${gitted_git_minor}" =~ ^[0-9]+$ ]]; then
    gitted_sanity_fail "Failed to parse Git version '${gitted_git_version_raw}'"
fi
if (( gitted_git_major < GITTED_GIT_MIN_MAJOR )) || \
    (( gitted_git_major == GITTED_GIT_MIN_MAJOR && gitted_git_minor < GITTED_GIT_MIN_MINOR )); then
    gitted_sanity_fail "Git version ${gitted_git_version_raw} is too old; gitted requires Git ${GITTED_GIT_MIN_MAJOR}.${GITTED_GIT_MIN_MINOR}.0 or higher"
fi

if ! "${GIT_BIN}" rev-parse --git-dir > /dev/null 2>&1; then
    gitted_sanity_fail "Oops, this is not a Git repository"
fi

root=$("${GIT_BIN}" rev-parse --show-toplevel)
cd "${root}"
# Imported from intro.sh when releasing:
help_pull=$(cat << EOT
Usage: pull

We pull from the upstream branch and then also from the upstream repository.
EOT
)

help_push=$(cat << EOT
Usage: push [<message> | <branch>]

You either provide a commit message or a name of the branch you push to. If the
argument is a single integer, we treat it as a branch name. Everything else
is treated as a plain message.
EOT
)

help_branch=$(cat << EOT
Usage: branch <name>

You either provide a "message" or a name of the branch you push to. If the
argument is a single integer, we treat it as a branch name. Everything else
is treated as a plain message.
EOT
)

help_commit=$(cat << EOT
Usage: commit [<message> | <branch>]

You either provide a commit message or a name of the branch you push to. If the
argument is a single integer, we treat it as a branch name. Everything else
is treated as a plain message.
EOT
)

#!/bin/bash
# SPDX-FileCopyrightText: Copyright (c) 2025 Yegor Bugayenko
# SPDX-License-Identifier: MIT

set -e -o pipefail

if [ "$1" = '--help' ]; then
    cmd=$(basename "$0")
    var="help_${cmd}"
    help=${!var}
    if [ -z "${help}" ]; then
        echo "Usage: ${cmd} --help"
    else
        echo "${help}"
    fi
    exit
fi

if [ -z "${GITTED_INTRODUCED}" ]; then
    printf "\e[1mGitted\e[0m 0.0.21 (https://github.com/yegor256/gitted)\n"
    GITTED_INTRODUCED=true
    export GITTED_INTRODUCED
fi
name=$1
if ! [[ "${name}" =~ ^[1-9][0-9]*$ ]]; then
    fail_it "Branch name must be a positive integer (GitHub issue number), got '${name}'"
fi

if "${GIT_BIN}" show-ref --verify --quiet "refs/heads/${name}"; then
    fail_it "Branch '${name}' already exists locally"
fi

# shellcheck disable=SC2154
title_it "Checking out the origin/${master} branch"
# shellcheck disable=SC2154
bash_it "${GIT_BIN}" checkout "${master}"

# shellcheck disable=SC2154
"${base}/pull"

title_it "Showing the current status"
bash_it "${GIT_BIN}" status

title_it "Checking out the origin/${name} branch"
bash_it "${GIT_BIN}" checkout -b "${name}"

while true; do
    title_it "Pushing to the origin/${name} branch"
    bash_it "${GIT_BIN}" push origin "${name}" && break
    if [ -n "${GITTED_TESTING}" ]; then
        exit 1
    fi
done

title_it "Setting the upstream of the origin/${name} branch"
bash_it "${GIT_BIN}" branch "--set-upstream-to=origin/${name}" "${name}"
