#!/bin/bash

unshallow_repo() {
  echo "[CI] Completando o repositorio para executar o processo"

  IS_SHALLOW=$(git rev-parse --is-shallow-repository)
  if $IS_SHALLOW; then
    git fetch --unshallow
  fi
  git fetch --all
}

get_next_version() {
  RELEASE_KIND=$1
  : "${RELEASE_KIND:?É obrigatório informar via parâmetro o tipo de release (major, minor ou patch)! }"

  VERSION=$2
  if [ -z "$VERSION" ]; then
      VERSION=$(git tag --sort=-v:refname | grep "^v[0-9]\{1,\}-[0-9]\{1,\}-[0-9]\{1,\}$" | head -1 | sed "s/-\([[:digit:]]\)/\.\1/g")
      if [ "$VERSION" == "" ]; then
          VERSION="v0.0.0"
      fi
  fi

  [[ "${VERSION:0:1}" == "v" ]] && VERSION=${VERSION:1}
  IFS='.' read -a VERSION_ARRAY <<< "$VERSION"

  MAJOR=${VERSION_ARRAY[0]}
  MINOR=${VERSION_ARRAY[1]}
  PATCH=${VERSION_ARRAY[2]}

  if [ "$RELEASE_KIND" == "major" ]; then
      NEW_MAJOR=$(($MAJOR+1))
      VERSION="$NEW_MAJOR.0.0"
  fi
  if [ "$RELEASE_KIND" == "minor" ]; then
      NEW_MINOR=$(($MINOR+1))
      VERSION="$MAJOR.$NEW_MINOR.0"
  fi
  if [ "$RELEASE_KIND" == "patch" ]; then
      NEW_PATCH=$(($PATCH+1))
      VERSION=$MAJOR.$MINOR.$NEW_PATCH
  fi
}

get_version_release_candidate() {
  unshallow_repo

  . senior-ci/release-candidate/${REPO}end/get_version.sh $RELEASE_KIND
}

push_branch_changes() {
  CI_REPOSITORY_URL_FOR_PUSH=$(echo "$CI_REPOSITORY_URL" | sed -e "s|.*@\(.*\)|git@\1|" -e "s|/|:|" )
  git remote set-url --push origin "$CI_REPOSITORY_URL_FOR_PUSH"
}

update_changelog() {
  update_changelog_version
  update_changelog_date
}

update_changelog_version() {
  echo "[CI] Atualizando placeholder {version} ($VERSION) no $CI_PROJECT_DIR/CHANGELOG.md"

  [[ $(grep --count "{version}" $CI_PROJECT_DIR/CHANGELOG.md) -lt 1 ]] && echo "[CI] Placeholder {version} not defined in $CI_PROJECT_DIR/CHANGELOG.md" && exit 1
  [[ $(grep --fixed-strings --count "# $VERSION" $CI_PROJECT_DIR/CHANGELOG.md) -ne 0 ]] && echo "[CI] Version $VERSION already defined in $CI_PROJECT_DIR/CHANGELOG.md" && exit 1

  sed -i 's/{version}/'"$VERSION"'/' $CI_PROJECT_DIR/CHANGELOG.md
}

update_changelog_date() {
  DAY=$(date +%d)
  MONTH=$(date +%m)
  YEAR=$(date +%Y)
  DATE="$DAY\/$MONTH\/$YEAR"

  echo "[CI] Atualizando placeholder {date} ($DATE) no $CI_PROJECT_DIR/CHANGELOG.md"

  [[ $(grep --count "{date}" $CI_PROJECT_DIR/CHANGELOG.md) -lt 1 ]] && echo "[CI] Placeholder {date} not defined in $CI_PROJECT_DIR/CHANGELOG.md"  && exit 1

  sed -i 's/{date}/'$DATE'/' $CI_PROJECT_DIR/CHANGELOG.md
}

commit_changelog_template_without_temp() {
  commit_changelog_template

  # Replace temp placeholder for no conflits
  sed -i 's/{versionTemp}/{version}/' $CI_PROJECT_DIR/CHANGELOG.md
  sed -i 's/{dateTemp}/{date}/' $CI_PROJECT_DIR/CHANGELOG.md

  git commit -a -m "[CI] Realizando a criação do template padrão do CHANGELOG"
}

commit_changelog_template() {
  if [ -n "$1" ]; then
      sed -i '1s|^|# '$1'\n|' $CI_PROJECT_DIR/CHANGELOG.md
      sed -i '2s|^|[{date}]\n\n|' $CI_PROJECT_DIR/CHANGELOG.md
  else
      sed -i '1s|^|# {versionTemp}\n|' $CI_PROJECT_DIR/CHANGELOG.md
      sed -i '2s|^|[{dateTemp}]\n\n|' $CI_PROJECT_DIR/CHANGELOG.md
  fi

  sed -i '4s|^|### Quebras de compatibilidade\n|' $CI_PROJECT_DIR/CHANGELOG.md
  sed -i '5s|^|* N\/A.\n\n|' $CI_PROJECT_DIR/CHANGELOG.md

  sed -i '7s|^|### Novas funcionalidades\n|' $CI_PROJECT_DIR/CHANGELOG.md
  sed -i '8s|^|* N\/A.\n\n|' $CI_PROJECT_DIR/CHANGELOG.md

  sed -i '10s|^|### Melhorias\n|' $CI_PROJECT_DIR/CHANGELOG.md
  sed -i '11s|^|* N\/A.\n\n|' $CI_PROJECT_DIR/CHANGELOG.md

  sed -i '13s|^|### Correções\n|' $CI_PROJECT_DIR/CHANGELOG.md
  sed -i '14s|^|* N\/A.\n\n|' $CI_PROJECT_DIR/CHANGELOG.md

  sed -i '16s|^|### Alterações na base de dados\n|' $CI_PROJECT_DIR/CHANGELOG.md
  sed -i '17s|^|* N\/A.\n\n|' $CI_PROJECT_DIR/CHANGELOG.md

  sed -i '19s|^|### Alteração de dependências\n|' $CI_PROJECT_DIR/CHANGELOG.md
  sed -i '20s|^|* N\/A.\n\n|' $CI_PROJECT_DIR/CHANGELOG.md

  git commit -a -m "[CI] Changelog para próxima versão" -m "[auto release]"
};

delete_empty_info_changelog() {
  echo "[CI] Removendo blocos vazios do changelog"

  # Delete N/A block on changelog for no useless information
  sed -i '/* N\/A./{!p; x; d;}; x; ${x;p;}' $CI_PROJECT_DIR/CHANGELOG.md
  sed -i '/* N\/A./{N;d}' $CI_PROJECT_DIR/CHANGELOG.md
  sed -i '1d' $CI_PROJECT_DIR/CHANGELOG.md
}

create_release_branch() {
  VERSION_HYPHEN=`echo "v$VERSION" | sed "s/\.\([[:digit:]]\)/-\1/g"`
  echo "[CI] Iniciando processo de GitFlow. Criando branch release/$VERSION_HYPHEN"
  git checkout -B release/$VERSION_HYPHEN
}

create_release_tag() {
  call_extension "before_change_changelog"
  delete_empty_info_changelog
  call_extension "after_change_changelog"

  rm -rf $CI_PROJECT_DIR/.npm/ $CI_PROJECT_DIR/.cache/ $CI_PROJECT_DIR/.m2/ .npm/ .cache/ .m2 **/.npm/ **/.cache/ **/.m2/

  git add -A
  git reset $CI_PROJECT_DIR/senior-ci/ $CI_PROJECT_DIR/venv/ senior-ci/ venv/ **/senior-ci/ **/venv/
  git commit -m "Criando versão $VERSION" -m "[skip ci]" -m "[auto release]"

  echo "[CI] Realizando o merge do branch release/$VERSION_HYPHEN para a master"
  git fetch --all

  git checkout master
  git reset --hard origin/master
  MERGE_MESSAGE=$(echo $(git rev-parse release/$VERSION_HYPHEN)$'\t\t'"branch 'release/$VERSION_HYPHEN'" | git fmt-merge-msg)
  git merge release/$VERSION_HYPHEN --no-ff -m "$MERGE_MESSAGE" -m "[auto release]" -X theirs

  echo "[CI] Criando a tag $VERSION_HYPHEN"
  git tag --force --annotate $VERSION_HYPHEN -m "Liberação versão $VERSION"

  echo "[CI] Realizando o merge da tag $VERSION_HYPHEN para a develop"
  git checkout develop
  git reset --hard origin/develop

  MERGE_MESSAGE=$(echo $(git rev-parse $VERSION_HYPHEN)$'\t\t'"tag '$VERSION_HYPHEN'" | git fmt-merge-msg)
  git merge $VERSION_HYPHEN --no-ff -m "$MERGE_MESSAGE" -m "[skip ci]" -m "[auto release]"

  call_extension "before_change_changelog"
  commit_changelog_template_without_temp
  call_extension "after_change_changelog"

  echo "[CI] Merges concluídos. Excluindo branch release/$VERSION_HYPHEN"
  git branch -D release/$VERSION_HYPHEN

  CI_REPOSITORY_URL_FOR_PUSH=$(echo "$CI_REPOSITORY_URL" | sed -e "s|.*@\(.*\)|git@\1|" -e "s|/|:|" )
  git remote set-url --push origin "$CI_REPOSITORY_URL_FOR_PUSH"

  git push --all --follow-tags

  echo "[CI] Processo de GitFlow concluído."
}
