#!/bin/bash -e
#
# Author:: Lance Albertson <lance@osuosl.org>
# Copyright:: Copyright 2024-2026, Cinc Project
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# FreeBSD build entry point.
#
# Same strategy as build/build-macos.sh: rename-aside the live
# /opt/omnibus-toolchain so the runner can be rolled back on any
# exit path, then RVM-bootstrap a clean ruby in the repo workspace
# (avoiding the shebang trap that breaks "use the renamed
# toolchain's binaries"). See build-macos.sh for the rationale.

TOP_DIR="$(pwd)"
export CI_PROJECT_DIR=${CI_PROJECT_DIR:-${TOP_DIR}}
export FORCE_UNSAFE_CONFIGURE=1
export rvm_path="${TOP_DIR}/rvm"

# Put Bundler's user-level cache + config inside the workspace
# instead of $HOME/.bundle, which is not always writable on
# self-hosted runners (FreeBSD's /var/tmp/gitlab_runner/.bundle
# has hit "It is likely that you need to grant write permissions").
export BUNDLE_USER_HOME="${TOP_DIR}/.bundle-user"
mkdir -p "${BUNDLE_USER_HOME}"

INSTALL_DIR="/opt/omnibus-toolchain"
BOOTSTRAP_DIR="/opt/omnibus-toolchain.bootstrap"

# Defuse stale TLS/CA settings that point at the install_dir we are
# about to rename aside. See build-macos.sh for the full explanation;
# in short, the runner's ~/.gitconfig has http.sslcainfo pointing at
# the live install, so we inject a per-process override that points
# at the bootstrap copy via GIT_CONFIG_COUNT.
unset GIT_SSL_CAINFO SSL_CERT_FILE SSL_CERT_DIR CURL_CA_BUNDLE
export GIT_CONFIG_NOSYSTEM=1
export GIT_CONFIG_COUNT=1
export GIT_CONFIG_KEY_0="http.sslcainfo"
export GIT_CONFIG_VALUE_0="${BOOTSTRAP_DIR}/embedded/ssl/certs/cacert.pem"

# Recover from a previous build that crashed before its trap could run.
if [ -d "${BOOTSTRAP_DIR}" ]; then
  if [ -x "${INSTALL_DIR}/embedded/bin/ruby" ]; then
    sudo rm -rf "${BOOTSTRAP_DIR}"
  else
    sudo rm -rf "${INSTALL_DIR}"
    sudo mv "${BOOTSTRAP_DIR}" "${INSTALL_DIR}"
  fi
fi

if [ ! -x "${INSTALL_DIR}/embedded/bin/ruby" ]; then
  echo "ERROR: no working toolchain at ${INSTALL_DIR}; cannot guarantee a clean rollback" >&2
  echo "Install a seed omnibus-toolchain on this runner first; see CINC_MAINTENANCE_PLAN.md" >&2
  exit 1
fi

RUNNER_USER="$(id -un)"
RUNNER_GROUP="$(id -gn)"

restore_state() {
  sudo rm -rf "${INSTALL_DIR}"
  sudo mv "${BOOTSTRAP_DIR}" "${INSTALL_DIR}"
  # The omnibus build runs under sudo on FreeBSD (writes to /opt
  # need root) and leaves root-owned files in cache/git_cache. If we
  # do not chown back, the next build's `git clean` cannot remove
  # them and the checkout fails with "Permission denied". Run the
  # chown from the trap so it fires even if the build is canceled
  # or crashes before reaching the explicit chown step.
  sudo chown -R "${RUNNER_USER}:${RUNNER_GROUP}" "${CI_PROJECT_DIR}" 2>/dev/null || true
}

sudo mv "${INSTALL_DIR}" "${BOOTSTRAP_DIR}"
trap restore_state EXIT

set -e
mkdir -p ${TOP_DIR}/cache/git_cache

GIT_CACHE="${TOP_DIR}/cache/git_cache/opt/omnibus-toolchain"
if [ -d "${GIT_CACHE}" ] && ! git --git-dir="${GIT_CACHE}" rev-parse --git-dir > /dev/null 2>&1; then
  echo "Git cache is corrupted, removing..."
  rm -rf "${GIT_CACHE}"
fi

grep -q '^cache_dir' omnibus.rb || {
  echo "cache_dir '${TOP_DIR}/cache'" >> omnibus.rb
  echo "git_cache_dir '${TOP_DIR}/cache/git_cache'" >> omnibus.rb
  # Match the macOS script: keep all omnibus working/output dirs in
  # the workspace rather than the default /var/cache/omnibus/*. Not
  # strictly required on FreeBSD where omnibus runs under sudo, but
  # keeps the cleanup surface area consistent — everything omnibus
  # writes lives under ${TOP_DIR} so the trap-chown sweep covers it.
  # Do NOT point package_dir at ${TOP_DIR}/pkg — omnibus's package_me
  # step copies the built package from package_dir to <project_root>/
  # pkg (project.rb:1159), and if those two are equal FileUtils.cp
  # raises "same file" after packaging completes.
  echo "source_dir '${TOP_DIR}/omnibus-src'" >> omnibus.rb
  echo "build_dir '${TOP_DIR}/omnibus-build'" >> omnibus.rb
  echo "package_dir '${TOP_DIR}/omnibus-pkg'" >> omnibus.rb
  echo "package_tmp '${TOP_DIR}/pkg-tmp'" >> omnibus.rb
  # Anchor ccache under the workspace too, matching the macOS script.
  # FreeBSD runs the build under sudo so the default
  # /var/cache/omnibus/cache/ccache would be writable, but keeping
  # ccache state next to the other omnibus dirs makes the trap-chown
  # sweep cover it and matches the pattern.
  echo "ccache_dir '${TOP_DIR}/cache/ccache'" >> omnibus.rb
  echo "use_git_caching true" >> omnibus.rb
}

# Disable RVM autolibs — the runner manages its own pkg toolchain,
# RVM should not try to satisfy deps via pkg/brew/etc.
curl -sSL https://get.rvm.io | bash
source "${TOP_DIR}/rvm/scripts/rvm"
rvm autolibs disable
rvm install ruby-3.4

gem sources --remove https://rubygems.org/ || true
gem sources --add https://rubygems.cinc.sh
gem sources --add https://rubygems.org

bundle config set --local path "${TOP_DIR}/vendor/bundle"
bundle config set --local without 'development'
bundle install

if [ -n "${AWS_ACCESS_KEY_ID:-}" ] ; then
  bundle exec omnibus cache populate
fi

sudo -E bash -c "source ${TOP_DIR}/rvm/scripts/rvm && bundle exec omnibus build omnibus-toolchain -l ${OMNIBUS_LOG_LEVEL:-info} --override append_timestamp:false"

# omnibus ran under sudo, so pkg/ and other workspace dirs ended up
# root-owned. Chown back NOW so the user-mode mv below can move the
# package artifacts out of pkg/. The EXIT trap also does this for
# cleanup/rollback purposes, but it fires too late for the artifact
# move.
sudo chown -R "${RUNNER_USER}:${RUNNER_GROUP}" "${CI_PROJECT_DIR}"

mkdir -p ${CI_PROJECT_DIR}/data
mv -v pkg/omnibus-toolchain* ${CI_PROJECT_DIR}/data/
