#!/bin/bash

# Slackware build script for ngspice-wave

# Copyright 2026 Alfredo USA
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
# permitted provided that the following conditions are met:
#
# 1. Redistributions of this script must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#
#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# ngspice-wave is a cargo workspace (codeberg.org/alto555/ngspice_wave) that
# builds the waveform viewer for the .raw files ngspice / ngspice-jit writes.
#
# Two things make this build unusually simple for a Rust program, and both are
# deliberate upstream: every crate is a path dependency inside the workspace --
# there is not one crates.io dependency, so the build never touches the network
# and needs no vendored-crate tarball -- and the X11 client is written against
# the wire protocol, so the binaries link libc and nothing else.  The stock
# Slackware 15.0 rust (1.58) is new enough for edition 2021.

cd $(dirname $0) ; CWD=$(pwd)

PRGNAM=ngspice-wave
VERSION=${VERSION:-0.1.0}
BUILD=${BUILD:-1}
TAG=${TAG:-_SBo}
PKGTYPE=${PKGTYPE:-tgz}

if [ -z "$ARCH" ]; then
  case "$( uname -m )" in
    i?86) ARCH=i586 ;;
    arm*) ARCH=arm ;;
       *) ARCH=$( uname -m ) ;;
  esac
fi

if [ ! -z "${PRINT_PACKAGE_NAME}" ]; then
  echo "$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE"
  exit 0
fi

TMP=${TMP:-/tmp/SBo}
PKG=$TMP/package-$PRGNAM
OUTPUT=${OUTPUT:-/tmp}

set -e

# Do not inherit the builder's umask: every directory this script creates with
# mkdir -p takes its mode from it, and a loose umask silently ships a package
# full of world-writable directories.
umask 022

rm -rf $PKG
mkdir -p $TMP $PKG $OUTPUT
cd $TMP
rm -rf $PRGNAM-$VERSION
tar xvf $CWD/$PRGNAM-$VERSION.tar.gz
cd $PRGNAM-$VERSION
chown -R root:root .
find -L . \
 \( -perm 777 -o -perm 775 -o -perm 750 -o -perm 711 -o -perm 555 \
  -o -perm 511 \) -exec chmod 755 {} \; -o \
 \( -perm 666 -o -perm 664 -o -perm 640 -o -perm 600 -o -perm 444 \
  -o -perm 440 -o -perm 400 \) -exec chmod 644 {} \;

# Keep cargo entirely inside $TMP: a build run as root must not write to
# /root/.cargo, and --offline/--locked make it an error (rather than a silent
# download) if a crates.io dependency is ever added upstream.  The release
# profile -- opt-level 3, thin LTO, one codegen unit -- is set in the
# workspace Cargo.toml, because the benchmark numbers upstream quotes are
# only meaningful with it.
export CARGO_HOME=$TMP/$PRGNAM-cargo-home
export CARGO_TARGET_DIR=$TMP/$PRGNAM-target
rm -rf $CARGO_HOME $CARGO_TARGET_DIR

cargo build --release --offline --locked \
  -p waveview \
  -p wave-plot

# wave-bench, the benchmark and correctness harness, is intentionally not
# installed: its "gen" mode writes multi-gigabyte test files.  Build it from
# the source tree if you want to run the suite.

mkdir -p $PKG/usr/bin
install -m 0755 $CARGO_TARGET_DIR/release/waveview  $PKG/usr/bin/waveview
install -m 0755 $CARGO_TARGET_DIR/release/wave-plot $PKG/usr/bin/wave-plot

find $PKG -print0 | xargs -0 file | grep -e "executable" -e "shared object" | grep ELF \
  | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null || true

PKGDOC=$PKG/usr/doc/$PRGNAM-$VERSION
mkdir -p $PKGDOC
install -m 0644 LICENSE README.md docs/USAGE.md $PKGDOC

# The key and mouse reference is generated by the viewer itself, so the copy
# in the docs can never drift from the binary that was just built.
$CARGO_TARGET_DIR/release/waveview --keys > $PKGDOC/keys.txt 2> /dev/null || true

cat $CWD/$PRGNAM.SlackBuild > $PKGDOC/$PRGNAM.SlackBuild

# Documentation is data, not programs.  Nothing under /usr/doc may be
# executable: it is meaningless for a text file or a PDF, and an executable
# bit on something a user was told is only documentation is a trap.  Normalise
# the whole tree rather than naming files one at a time, so a doc added later,
# or one that arrives 0755 from upstream, cannot reintroduce it.  This also
# fixes the modes on the two files created by redirection above, which would
# otherwise follow the builder's umask.
find $PKGDOC -type f -exec chmod 0644 {} \;
find $PKGDOC -type d -exec chmod 0755 {} \;

mkdir -p $PKG/install
cat $CWD/slack-desc > $PKG/install/slack-desc
cat $CWD/doinst.sh > $PKG/install/doinst.sh
chmod 0644 $PKG/install/slack-desc $PKG/install/doinst.sh

cd $PKG
/sbin/makepkg -l y -c n $OUTPUT/$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE
