#!/usr/bin/ksh

# automatically convert tag_release to upper case
typeset -u tag_release

URL="git@github.com:ledgersmb/LedgerSMB.git"
#URL=/home/ehuelsmann/releases/lsmb-repo-2
branch="$1"
release_version="$2"
new_dev_version="$3"
sf_user="$4"
checkout_dir="LedgerSMB"
release_key="8DA0AF10"
frs_prj_dir="/home/frs/project/l/le/ledger-smb/"
frs_tagged_dir="Releases"
frs_untagged_dir="Beta Releases"
tag_release="Y"

if [[ -n $(echo "$release_version" | grep -- "-") ]]; then
   echo "Version modifier detected (rc/beta/...).
Modified versions don't get tagged. Force tag? [y/N]"
   read tag_release
fi

if [[ -n "$DEBUG_RELEASE" ]]; then
   set -x
fi

fail() {
   echo -e "$1\n" >&2
   exit 1
}

verify_dependency() {
   which_executable=$(which $1)
   eval $1="$which_executable"
   if [[ -z "$which_executable" ]]; then
      fail "Missing dependency: $1"
   fi
}

verify_dependencies() {
   verify_dependency "find"
   verify_dependency "sftp"
   verify_dependency "gpg"
   verify_dependency "git"
   verify_dependency "sed"
   verify_dependency "grep"
   verify_dependency "tar"
   verify_dependency "perl"
   verify_dependency "mktemp"
   verify_dependency "less"
   verify_dependency "gzip"
   verify_dependency "awk"
   verify_dependency "sha256sum"
   verify_dependency "sftp"
   verify_dependency "tx"
   verify_dependency "make"
   verify_dependency "msgmerge"
   verify_dependency "msguniq"
}

verify_release_key() {
   if [[ -z $($gpg --list-secret-keys | $grep "/$release_key") ]] ; then
     fail "No key with ID '$release_key' (release key) available!"
   fi
}

setup_workspace() {
   our_workspace=$($mktemp -d)
   trap "rm -rf '$our_workspace'" TERM EXIT
}

populate_workspace() {
   ( cd $our_workspace && \
    $git clone --recursive --single-branch --branch "$branch" "$URL" "$checkout_dir" ) \
   || fail "Failed to check out branch '$branch' from '$URL'!"
   if test -e "$our_workspace/$checkout_dir/LedgerSMB.pm" ;
   then
     LedgerSMBpm_path="LedgerSMB.pm"
   else
     LedgerSMBpm_path="lib/LedgerSMB.pm"
   fi
   echo "LedgerSMB.pm found at $LedgerSMBpm_path"
   #cp $our_workspace/$checkout_dir/conf/ledgersmb.conf.default $our_workspace/$checkout_dir/ledgersmb.conf 2>/dev/null
}

update_translations() {
   (cd "$our_workspace/$checkout_dir" && \
    $tx pull -f -a && utils/devel/rebuild_pot.sh && \
    ($find . -name '*~' -exec rm \{} + ) && \
    ($find . -name '*.orig' -exec rm \{} + ) && \
    $git add --all locale && git commit -m "* Automated release language update" \
    && $git push origin "$branch") \
   || fail "Failed to update branch ($branch) translations"
}

detect_current_version() {
   current_version=$(
     cd "$our_workspace/$checkout_dir"
     $sed -ne "/^our \$VERSION/ {
  s/^our \$VERSION = '\\(.*\\)';\$/\\1/
  p
}" "$LedgerSMBpm_path" )
   if [[ -z "$current_version" ]] ; then
     fail "Failed to detect current version!"
   fi
}

version_to_regex() {
   echo "$1" | $sed 's/\./\\./g'
}

detect_versionpatch_files() {
   versionpatch_regex=$(version_to_regex "$current_version")
   versionpatch_files=$(grep -lRE "$versionpatch_regex" "$our_workspace/$checkout_dir" | grep -v Changelog)
   if [[ -z "$versionpatch_regex" || -z "$versionpatch_files" ]]; then
     fail "Failed to detect which files to patch for version update!"
   fi
}

patch_version() {
   version_regex=$(version_to_regex "$1")
   new_version=$2
   $sed -i -e "s/$version_regex/$new_version/" $versionpatch_files \
   || fail "Failed to patch files for version update!"
}

show_release_parameters() {
clear
echo "
Please review details below!
Continuing will commit the diff shown and create a new version tag!


Release details
Git URL: $URL
Branch: $branch
Current version: $current_version
To be released: $release_version

Git config used for tag:
$($git config --list | $grep -E 'user.(email|name)')

Patched files:
$(echo "$versionpatch_files" | $sed -e "s#$our_workspace/$checkout_dir/##g")

Patch diff:
$(cd "$our_workspace/$checkout_dir" && $git diff )
" | $less

}

commit_versionupdate() {
   (cd "$our_workspace/$checkout_dir" && \
    $git commit -am "Update version" ) \
   || fail "Failed to commit version update patch!"
}

commit_versiontag() {
   (cd "$our_workspace/$checkout_dir" && \
    $git tag -m "$release_version" "$release_version" ) \
   || fail "Failed to tag version $release_version!"
}

create_versiontarball() {
   (cd "$our_workspace/$checkout_dir" && \
    $make dist DIST_DIR=../ DIST_VER=$release_version ) \
   || fail "Failed to create release archive!"
}

sign_versiontarball() {
   echo -n "Signing ledgersmb-$release_version.tar.gz\n"
   $gpg -u "$release_key" \
        -a -b "$our_workspace/ledgersmb-$release_version.tar.gz" \
   || fail "Failed to sign release archive!"
   echo "Succesfully signed release archive; directory content:

$(ls -lh "$our_workspace")
"
}

update_remote() {
   (cd "$our_workspace/$checkout_dir" && \
    $git push --follow-tags origin "$branch" ) \
   || fail "Failed to update the origin repository!"
}

publish_files() {
   (cd "$our_workspace" && \
    echo "cd '$frs_prj_dir/$prj_sub_dir'
mkdir '$release_version'
cd '$release_version'
put 'ledgersmb-$release_version.tar.gz.asc'
put 'ledgersmb-$release_version.tar.gz'
" | $sftp -b - "${sf_user}@frs.sourceforge.net") \
   || fail "Failed to upload files to sourceforge!"
}


extract_changelog_internal() {
   extract_version=${1:-$release_version}
   escaped_version=$(echo "$extract_version" | $sed -e 's/\./\./g')
   extracted_changelog=$(cd "$our_workspace/$checkout_dir" && \
     $awk "
BEGIN {
   matched=0;
   printing=0;
}
/Changelog for/ {
   printing=0;
}
/Changelog for $escaped_version/ {
   if(!matched) {
       matched=1;
       printing=1;
   }
}
{
   if (printing) {
       print;
   }
}" Changelog)
}

extract_changelog() {
   extract_changelog_internal

   if [[ -z $extracted_changelog && \
         -n $(echo "$release_version" | $grep -- "-rc") ]] ; then
     extract_changelog_internal $(echo "$release_version" | $sed -e 's/-rc.*//')
  fi
}

extract_sha256sum() {
   extracted_sha256sums=$(cd "$our_workspace" && \
     $sha256sum ledgersmb-$release_version.tar.gz* )
}

verify_dependencies
verify_release_key
setup_workspace
populate_workspace

if [[ -z "$(cd "$our_workspace/$checkout_dir"; $git tag | grep -E "^$release_version$")" ]]
then
  update_translations
  detect_current_version
  detect_versionpatch_files
  patch_version "$current_version" "$release_version"

  show_release_parameters
  commit_versionupdate
  commit_versiontag
  patch_version "$release_version" "$new_dev_version"
  commit_versionupdate
else
  tag_release="N"
fi

create_versiontarball
sign_versiontarball

typeset -u yn
echo -n "Ready to publish now. Proceed? [y/N] "
read yn
if [[ "$yn" != "Y" ]]; then
   fail "Aborted by user!"
fi

if [[ "$tag_release" == "Y" ]]; then
   # if we don't have a release tag, be sure to discard it!
   update_remote
   prj_sub_dir="$frs_tagged_dir"
else
   prj_sub_dir="$frs_untagged_dir"
fi
publish_files

extract_changelog
extract_sha256sum
prj_url_dir=$(echo "$prj_sub_dir" | sed -e 's/ /%20/g')

clear
echo "
Proposed wording for a release mail:

--------------------------------
Subject: LedgerSMB $release_version released

The LedgerSMB development team is happy to announce yet another new
version of its open source ERP and accounting application. This release
contains the following fixes and improvements:

$extracted_changelog

The release can be downloaded from sourceforge at
  https://sourceforge.net/projects/ledger-smb/files/$prj_url_dir/$release_version/

These are the sha256 checksums of the uploaded files:
$extracted_sha256sums


--------------------------------


All automated steps completed.

Please execute the following steps manually:

 * Update the latest/default download version on SourceForge
   [put link here]
 * Update the latest version on Wikipedia
   - https://en.wikipedia.org/w/index.php?title=LedgerSMB&action=edit
   - https://es.wikipedia.org/w/index.php?title=LedgerSMB&action=edit
 * Publish a release on GitHub by converting the tag
 * Send out the release announcement to
   - ledger-smb-announce@lists.sourceforge.net
   - ledger-smb-users@lists.sourceforge.net
   - ledger-smb-devel@lists.sourceforge.net
 * Publish the release announcement using the 'release' content type
   on ledgersmb.org (http://ledgersmb.org/node/add/release when logged in)
   [Note: Don't forget to set the correct branch to '$branch'!]
"

exit 0
