#!/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.

# Linux build entry point. The Cinc Linux toolchain is built inside a
# bare distro container (debian/almalinux/rocky/ubuntu/amazonlinux) — we
# cannot use the cincproject/omnibus-* base images here because *we* are
# what they install. So this script is responsible for bootstrapping a
# Ruby + bundler + omnibus environment from scratch.

TOP_DIR="$(pwd)"
export CI_PROJECT_DIR=${CI_PROJECT_DIR:-${TOP_DIR}}
# Needed to build gtar properly (configure refuses to run as root by default)
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, so the build does not depend on $HOME
# being writable.
export BUNDLE_USER_HOME="${TOP_DIR}/.bundle-user"
mkdir -p "${BUNDLE_USER_HOME}"

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

# Validate git cache - remove if corrupted
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
  echo "use_git_caching true" >> omnibus.rb
  # Anchor ccache under ${TOP_DIR}/cache/ so the GitLab CI cache
  # (cache: paths: cache/* in ci/package.yml) covers it alongside
  # the omnibus git_cache. Self-hosted runners (FreeBSD, macOS,
  # Windows) keep the default ccache_dir under base_dir, which is
  # naturally persistent on those runners.
  echo "ccache_dir '${TOP_DIR}/cache/ccache'" >> omnibus.rb
}

# Install distro build deps. The cincproject/omnibus-* images would
# normally cover this, but we bootstrap from upstream base images.
if command -v dnf &>/dev/null; then
  # Enable extra repos that ship libyaml-devel and several perl
  # split-out subpackages. EL8 keeps them in PowerTools, EL9/10 in
  # CRB. EPEL covers anything that landed there instead. Repo names
  # vary by RHEL version, so try each and tolerate the misses.
  dnf -y install dnf-plugins-core
  dnf config-manager --enable powertools 2>/dev/null || true
  dnf config-manager --enable crb 2>/dev/null || true
  dnf -y install epel-release 2>/dev/null || true

  # perl-FindBin and perl-lib are split out into their own
  # subpackages on EL9+; on EL8 they live inside the base `perl`
  # package and the standalone names do not resolve. Match the
  # cinc-omnibus cookbook's logic and request the subpackages only
  # when the major version is >= 9. On Amazon Linux the `rhel` macro
  # is undefined: `rpm -E '%{rhel}'` exits 0 and prints the literal
  # "%{rhel}", so normalize any non-numeric output to 0.
  EL_MAJOR=$(rpm -E '%{rhel}' 2>/dev/null || echo 0)
  [[ "${EL_MAJOR}" =~ ^[0-9]+$ ]] || EL_MAJOR=0
  if [ "${EL_MAJOR}" -ge 9 ]; then
    EL_PERL_SUBPKGS="perl-FindBin perl-lib"
  else
    EL_PERL_SUBPKGS=""
  fi

  dnf install -y --allowerasing autoconf bison flex gcc gcc-c++ gettext kernel-devel \
    make m4 ncurses-devel patch git rpm-build which procps-ng curl \
    perl perl-Digest-SHA perl-IPC-Cmd perl-bignum ${EL_PERL_SUBPKGS} \
    perl-Time-Piece perl-Pod-Html perl-podlators \
    automake pkgconf pkgconf-m4 \
    libyaml-devel openssl-devel readline-devel zlib-devel libffi-devel

  # ccache is a build accelerator, not a requirement. Two skip cases:
  #
  # 1. Amazon Linux 2023 ships neither ccache nor a working EPEL out
  #    of the box, so the install just fails.
  # 2. ppc64le runners have ccache 3.x, whose direct-mode preprocessor
  #    output trips ncurses's MKlib_gen.sh ("_Bool after # is not a
  #    positive integer"). Skip until the toolchain itself bundles a
  #    ccache 4.x that we can use to shadow the host's via PATH.
  #
  # In both cases omnibus's `ccache_available?` check (which looks
  # for ccache on PATH) silently skips wrapping CC/CXX when ccache
  # is missing — the build runs without compiler caching.
  if [ "$(uname -m)" = "ppc64le" ]; then
    echo "Skipping ccache install on ppc64le; awaiting ccache 4.x bundled in the toolchain"
  else
    dnf install -y --allowerasing ccache 2>/dev/null || \
      echo "ccache not available on this distro; build will proceed without compiler caching"
  fi
elif command -v apt &>/dev/null; then
  # Prevent tzdata (pulled in transitively) from blocking on its
  # geographic-area prompt under Ubuntu 20.04 et al.
  export DEBIAN_FRONTEND=noninteractive
  apt update
  # curl is not in the Ubuntu 26.04 base image; install it so the RVM
  # bootstrap below has something to download with.
  apt -y install autoconf bison build-essential flex gettext \
    libncurses-dev libssl-dev libreadline-dev zlib1g-dev git curl \
    libffi-dev debianutils procps dpkg-dev devscripts automake pkgconf \
    libyaml-dev ccache
elif command -v zypper &>/dev/null; then
  # openSUSE Leap: no dnf/apt metapackage, so spell out the toolchain and
  # -devel headers (RVM's ruby-build step requires readline-devel). The
  # resolution flags let the image's libncurses6 step back to match the
  # older ncurses-devel the repos offer. glibc-locale adds a UTF-8 locale.
  zypper --non-interactive --gpg-auto-import-keys refresh
  zypper --non-interactive install --allow-downgrade --force-resolution \
    autoconf automake bison flex gawk gcc gcc-c++ gettext-tools \
    make m4 patch which curl git rpm-build pkgconf procps \
    tar gzip glibc-locale glibc-i18ndata \
    libffi-devel libopenssl-devel libyaml-devel ncurses-devel readline-devel \
    zlib-devel ccache
fi

# Bootstrap Ruby via RVM (omnibus and bundler need a working Ruby
# before we can build the embedded one)
curl -sSL https://get.rvm.io | bash
source "${TOP_DIR}/rvm/scripts/rvm"
rvm install ruby-3.4

# Prefer the Cinc rubygems mirror so we pick up our forked gems
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

bundle exec omnibus build omnibus-toolchain \
  -l ${OMNIBUS_LOG_LEVEL:-info} \
  --override append_timestamp:false

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