#!/usr/bin/env bash

set -e

# This is not portable. It has bashisms.

BUILD_TIME="$(date '+%s')"
BUILD_USER="$(whoami)"
BUILD_SUDO_USER="${SUDO_USER}"
BUILD_HOST="$(hostname)"

# Check to make sure git is available.
if ! command -v git &> /dev/null;
then
  echo "Git is not available; automatic version handling unsupported."
  echo "You must build by calling 'go build' directly in the respective directories."
  exit 0
fi

# Check git directory/repository.
if ! git rev-parse --is-inside-work-tree &>/dev/null;
then
  echo "Not running inside a git work tree; automatic version handling unsupported/build script unsupported."
  echo "You must build by calling 'go build' directly in the respective directories instead."
  exit 0
fi

# The repo URI for origin.
REPO_URI="$(git remote get-url origin)"

# If it has a tag in the path of the current HEAD that matches a version string...
# I wish git describe supported regex. It does not; only globs. Gross.
# If there's a bug anywhere, it's here.
if git describe --tags --abbrev=0 --match "v[0-9]*" HEAD &> /dev/null;
then
  # It has a tag we can use.
  CURRENT_VER="$(git describe --tags --abbrev=0 --match "v[0-9]*" HEAD)"
  COMMITS_SINCE="$(git rev-list --count ${CURRENT_VER}..HEAD)"
else
  # No tag available.
  CURRENT_VER=""
  COMMITS_SINCE=""
fi

# If it's dirty (staged but not committed or unstaged files)...
if ! git diff-index --quiet HEAD;
then
  # It's dirty.
  IS_DIRTY="1"
else
  # It's clean.
  IS_DIRTY="0"
fi

# Get the commit hash of the *most recent* commit in the path of current HEAD...
CURRENT_HASH="$(git rev-parse --verify HEAD)"
# The same as above, but abbreviated.
CURRENT_SHORT="$(git rev-parse --verify --short HEAD)"

# Get the module name.
MODPATH="$(sed -n -re 's@^\s*module\s+(.*)(//.*)?$@\1@p' go.mod)"

# Build the ldflags string.
LDFLAGS_STR="\
-X '${MODPATH}/version.repoUri=${REPO_URI}' \
-X '${MODPATH}/version.sourceControl=git' \
-X '${MODPATH}/version.version=${CURRENT_VER}' \
-X '${MODPATH}/version.commitHash=${CURRENT_HASH}' \
-X '${MODPATH}/version.commitShort=${CURRENT_SHORT}' \
-X '${MODPATH}/version.numCommitsAfterTag=${COMMITS_SINCE}' \
-X '${MODPATH}/version.isDirty=${IS_DIRTY}' \
-X '${MODPATH}/version.buildTime=${BUILD_TIME}' \
-X '${MODPATH}/version.buildUser=${BUILD_USER}' \
-X '${MODPATH}/version.buildSudoUser=${BUILD_SUDO_USER}' \
-X '${MODPATH}/version.buildHost=${BUILD_HOST}'"


# And finally build.
export CGO_ENABLED=0

mkdir -p ./bin/

cmd="subnetter"
# Linux
bin="${cmd}"
echo "Building ./bin/${bin}..."
go build \
	-o "./bin/${bin}" \
	-ldflags \
		"${LDFLAGS_STR}" \
  cmd/${cmd}/*.go
echo " Done."

# Windows
GOOS="windows"
bin="subnetter.exe"
echo "Building ./bin/${bin}..."
go build \
	-o "./bin/${bin}" \
	-ldflags \
		"${LDFLAGS_STR}" \
  cmd/${cmd}/*.go
echo " Done."

# macOS
GOOS="darwin"
## x86_64
bin="subnetter.x86_64.app"
echo "Building ./bin/${bin}..."
go build \
	-o "./bin/${bin}" \
	-ldflags \
		"${LDFLAGS_STR}" \
  cmd/${cmd}/*.go
echo " Done."
## ARM64 (m1/m2/... etc.; "Apple Silicon")
GOARCH="arm64"
bin="subnetter.m1.app"
echo "Building ./bin/${bin}..."
go build \
	-o "./bin/${bin}" \
	-ldflags \
		"${LDFLAGS_STR}" \
  cmd/${cmd}/*.go
echo " Done."

echo "Build complete."