#!/bin/sh
set -e

root_dir=$(dirname "$0")
root_dir=$(cd "$root_dir/.." && pwd)
if [ ! -f "$root_dir/LICENSE.txt" ]; then
	echo "Couldn't find the root dir"
	exit 1
fi
pysrc_dir="$root_dir/src/rust/iced-x86-py"
cargo_toml="$pysrc_dir/Cargo.toml"

if [ "$OSTYPE" = "msys" ]; then
	is_windows=y
else
	is_windows=n
fi

if [ "$is_windows" = "y" ]; then
	python=python
else
	python=python3
fi
full_check=y
gen_docs=y
sdist_only=n
set_rustflags=y
delete_old_venv=y

new_func() {
	echo
	echo "****************************************************************"
	echo "$1"
	echo "****************************************************************"
	echo
}

patchci_verify_not_patched() {
	# msys grep fails if we use $
	if ! grep -E '^#pathci' "$cargo_toml" 2>&1 > /dev/null; then
		echo "Cargo.toml is patched"
		exit 1
	fi
}

patchci_verify_patched() {
	# msys grep fails if we use $
	if grep -E '^#pathci' "$cargo_toml" 2>&1 > /dev/null; then
		echo "Cargo.toml is not patched"
		exit 1
	fi
}

# We must reference the current iced-x86 code so we can't use the crates.io crate
# since it hasn't been pushed yet. We patch py/Cargo.toml to point to the current
# source code.
#
# The sdist's Cargo.toml must be the original file though or they won't be able
# to build it once it's been published.
patchci_patch() {
	patchci_verify_not_patched

	curr_dir=$(pwd)
	cd "$root_dir"

	if [ "$OSTYPE" = "msys" ]; then
		iced_x86_dir="$(pwd -W)/src/rust/iced-x86"
	else
		iced_x86_dir="$(pwd)/src/rust/iced-x86"
	fi
	if [ ! -d "$iced_x86_dir" ]; then
		echo "Dir does not exist: $iced_x86_dir"
		exit 1
	fi

	sed -i -e "s&^#pathci$&path = \"$iced_x86_dir\"&" "$cargo_toml"

	cd "$curr_dir"
}

patchci_undo_patch() {
	git checkout "$cargo_toml"
}

generate_sdist() {
	new_func "Generate sdist"

	curr_dir=$(pwd)
	cd "$pysrc_dir"

	patchci_verify_not_patched

	python -m build --sdist

	cd "$curr_dir"
}

verify_license_file() {
	if [ ! -f "$pysrc_dir/LICENSE.txt" ]; then
		echo "Missing license file"
		exit 1
	fi
	cp "$root_dir/LICENSE.txt" "$pysrc_dir/"
	git diff --exit-code
}

generate_wheel() {
	new_func "Generate wheel"

	curr_dir=$(pwd)
	cd "$pysrc_dir"

	patchci_verify_patched

	python -m build --wheel

	cd "$curr_dir"
}

test_wheel() {
	new_func "Test wheel"

	curr_dir=$(pwd)
	cd "$pysrc_dir"

	patchci_verify_patched

	python -m pip install iced-x86 --no-index -f dist --only-binary iced-x86
	python -m pytest --color=yes --code-highlight=yes

	cd "$curr_dir"
}

generate_docs() {
	new_func "Generate docs"

	curr_dir=$(pwd)
	cd "$pysrc_dir"

	patchci_verify_patched

	# Depends on generate_wheel output.
	if [ ! -f "$(ls dist/iced_x86-*-linux_x86_64.whl)" ]; then
		echo "Couldn't find the built wheel file"
		exit 1
	fi
	wheel=$(ls dist/iced_x86-*-linux_x86_64.whl)
	rm -rf build/unpacked-wheel/
	mkdir -p build/unpacked-wheel/
	unzip "$wheel" -d build/unpacked-wheel/

	echo "Generating HTML files"
	#TODO: enable -W again, fails in GitHub Actions (py3.8) but not locally (py3.11)
	python -m sphinx --color -n --keep-going -b html docs docs/_build

	echo "Running doc tests"
	python -m sphinx --color -n -W --keep-going -b doctest docs docs/_build

	cd "$curr_dir"
}

misc_tests() {
	new_func "clippy, fmt, pylint, mypy"

	curr_dir=$(pwd)
	cd "$pysrc_dir"

	patchci_verify_patched

	echo "==== CLIPPY RELEASE ===="
	cargo clippy --color always --release

	echo "==== FORMAT CHECK ===="
	cargo fmt -- --color always --check

	echo "mypy"
	python -m mypy --version
	python -m mypy --strict src/iced_x86
	python -m pip install iced-x86 --no-index -f dist --only-binary iced-x86
	python -m mypy --strict tests/

	echo "pylint"
	# It will fail to load _iced_x86_py since it's not in the correct dir, so disable the error
	python -m pylint --version
	python -m pylint src/iced_x86 -d import-error --rcfile="$pysrc_dir/../pylintrc"

	cd "$curr_dir"
}

while [ "$#" -gt 0 ]; do
	case $1 in
	--quick-check) full_check=n ;;
	--sdist-only) sdist_only=y ;;
	--python) shift; python=$1 ;;
	--no-docs) gen_docs=n ;;
	--no-set-rustflags) set_rustflags=n ;;
	--no-delete-venv) delete_old_venv=n ;;
	*) echo "Unknown arg: $1"; exit 1 ;;
	esac
	shift
done

echo
echo "=================================================="
echo "Python build"
echo "=================================================="
echo

if [ "$set_rustflags" = "y" ]; then
	export RUSTFLAGS="-D warnings"
fi

echo "rustup show"
rustup show
echo "cargo version"
cargo --version
echo "Rust version"
rustc --version
echo "Python version"
$python --version

if [ "$delete_old_venv" = "y" ]; then
	echo "Deleting old .venv: $pysrc_dir/.venv/"
	rm -rf "$pysrc_dir/.venv/"
fi
$python -m venv "$pysrc_dir/.venv/"
. "$pysrc_dir/.venv/bin/activate"
echo "Installing dependencies..."
python -m pip install -r "$pysrc_dir/requirements-dev.txt"

verify_license_file

if [ "$sdist_only" = "y" ]; then
	generate_sdist
	exit 0
fi

echo "pytest version"
python -m pytest --version

if [ "$full_check" = "y" ] && [ "$gen_docs" = "y" ]; then
	echo "sphinx version"
	python -m sphinx --version
fi

generate_sdist
patchci_patch
generate_wheel
test_wheel
if [ "$full_check" = "y" ]; then
	misc_tests
	if [ "$gen_docs" = "y" ]; then
		generate_docs
	fi
fi
patchci_undo_patch
