#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$0")"
tmp=$(mktemp -d)
trap 'rm -rf "$tmp"' EXIT

expect_failure() {
  printf '\n$'; printf ' %q' "$@"; printf '\n'
  set +e
  "$@"
  code=$?
  set -e
  printf 'exit=%s (expected nonzero)\n' "$code"
  test "$code" -ne 0
}

printf '%s\n' '== environment =='
go version
go env GOOS GOARCH CGO_ENABLED CC GOEXPERIMENT
gcc --version | sed -n '1p'
for demo in reflectdemo unsafedemo cgodemo embeddemo gendemo; do
  printf '\n$ go run ./%s\n' "$demo"
  go run "./$demo"
done
printf '\n$ go test -count=1 ./...\n'
go test -count=1 ./...
printf '\n$ go vet ./...\n'
go vet ./...
printf 'vet exit=0\n'
printf '\n$ go test -race -count=1 ./...\n'
go test -race -count=1 ./...
printf '\n$ go test -gcflags=all=-d=checkptr=2 -count=1 ./...\n'
go test -gcflags=all=-d=checkptr=2 -count=1 ./...
printf '\n$ GOEXPERIMENT=cgocheck2 go test -count=1 ./cgodemo\n'
GOEXPERIMENT=cgocheck2 go test -count=1 ./cgodemo

expect_failure env CGO_ENABLED=0 go build -o "$tmp/cgo-disabled" ./cgodemo
expect_failure go vet ./testdata/unsafe_bad
expect_failure env GODEBUG=cgocheck=1 go run ./testdata/cgo_bad
expect_failure go build -o "$tmp/bad" ./testdata/embed_missing
expect_failure go build -o "$tmp/bad" ./testdata/embed_escape

cp go.mod "$tmp/go.mod"
cp -R gendemo embeddemo "$tmp/"
(
  cd "$tmp"
  printf '\n== generation is explicit ==\n'
  rm gendemo/greeting_gen.go
  expect_failure go build -o generated ./gendemo
  printf '\n$ go generate ./gendemo\n'
  go generate ./gendemo
  go build -o generated ./gendemo
  ./generated
  printf 'hello v2\n' > gendemo/message.txt
  printf '\n$ go build -o generated ./gendemo # input changed, no generate\n'
  go build -o generated ./gendemo
  ./generated
  printf '\n$ go generate ./gendemo\n'
  go generate ./gendemo
  go build -o generated ./gendemo
  ./generated
  before=$(sha256sum gendemo/greeting_gen.go)
  go generate ./gendemo
  after=$(sha256sum gendemo/greeting_gen.go)
  test "$before" = "$after"
  printf 'repeat generation: same SHA-256\n'

  printf '\n== embed is a build-time snapshot ==\n'
  go build -o embedded ./embeddemo
  printf 'changed\n' > embeddemo/assets/hello.txt
  printf 'old binary: '
  ./embedded | sed -n '1p'
  go build -o embedded ./embeddemo
  printf 'rebuilt binary: '
  ./embedded | sed -n '1p'
)
