#!/bin/sh
set -e

if [ -z "$AUTOPKGTEST_TMP" ]; then
    AUTOPKGTEST_TMP=$(mktemp -d)
    trap 'rm -rf "$AUTOPKGTEST_TMP"' EXIT
fi

export HOME="$AUTOPKGTEST_TMP/home"
mkdir -p "$HOME"

export http_proxy=127.0.0.1:9
export https_proxy=127.0.0.1:9
export HTTP_PROXY=127.0.0.1:9
export HTTPS_PROXY=127.0.0.1:9

WORKDIR="$AUTOPKGTEST_TMP/work"
mkdir -p "$WORKDIR"
cp -r debian/tests/test-001-artifacts/* "$WORKDIR/"

# Create empty mock repos for unused Bazel builtin module deps
MOCK_DIR="$AUTOPKGTEST_TMP/mock"
for mod in apple_support aspect_rules_js buildozer protobuf zlib; do
    mkdir -p "$MOCK_DIR/$mod"
    cat > "$MOCK_DIR/$mod/MODULE.bazel" <<EOF
module(name = "$mod", version = "999.0.0")
EOF
    touch "$MOCK_DIR/$mod/BUILD.bazel"
done

mkdir -p "$MOCK_DIR/aspect_rules_js/js"
touch "$MOCK_DIR/aspect_rules_js/js/BUILD.bazel"
cat > "$MOCK_DIR/aspect_rules_js/js/defs.bzl" << 'EOF'
def js_binary(**kwargs):
    pass
EOF

mkdir -p "$MOCK_DIR/protobuf/bazel" "$MOCK_DIR/protobuf/bazel/toolchains"
cat > "$MOCK_DIR/protobuf/BUILD.bazel" << 'EOF'
package(default_visibility = ["//visibility:public"])

sh_binary(
    name = "protoc",
    srcs = ["protoc.sh"],
)
EOF
printf '#!/bin/sh\nexec /usr/bin/protoc "$@"\n' > "$MOCK_DIR/protobuf/protoc.sh"
chmod +x "$MOCK_DIR/protobuf/protoc.sh"
touch "$MOCK_DIR/protobuf/bazel/BUILD.bazel" "$MOCK_DIR/protobuf/bazel/toolchains/BUILD.bazel"
cat > "$MOCK_DIR/protobuf/bazel/proto_library.bzl" << 'EOF'
def proto_library(**kwargs):
    native.proto_library(**kwargs)
EOF
cat > "$MOCK_DIR/protobuf/bazel/cc_proto_library.bzl" << 'EOF'
def cc_proto_library(**kwargs):
    native.cc_proto_library(**kwargs)
EOF
cat > "$MOCK_DIR/protobuf/bazel/toolchains/proto_lang_toolchain.bzl" << 'EOF'
def proto_lang_toolchain(**kwargs):
    native.proto_lang_toolchain(**kwargs)
EOF

# Setup Rust toolchain and tinyjson mock repos for rules_rust
RUST_TRIPLE=$(rustc -vV | sed -n 's/^host: //p')

mkdir -p "$MOCK_DIR/tinyjson/src"
cp -a /usr/share/cargo/registry/tinyjson-*/src/* "$MOCK_DIR/tinyjson/src/"
cat > "$MOCK_DIR/tinyjson/MODULE.bazel" << 'EOF'
module(name = "rules_rust_tinyjson")
EOF
cat > "$MOCK_DIR/tinyjson/BUILD.bazel" << 'EOF'
load("@rules_rust//rust/private:rust.bzl", "rust_library_without_process_wrapper")

package(default_visibility = ["//visibility:public"])

rust_library_without_process_wrapper(
    name = "tinyjson",
    srcs = glob(["src/*.rs"]),
    edition = "2018",
)
EOF

mkdir -p "$MOCK_DIR/cargo_bazel"
cat > "$MOCK_DIR/cargo_bazel/MODULE.bazel" << 'EOF'
module(name = "cargo_bazel")
EOF
cat > "$MOCK_DIR/cargo_bazel/BUILD.bazel" << 'EOF'
package(default_visibility = ["//visibility:public"])

filegroup(
    name = "cargo-bazel",
    srcs = ["cargo-bazel"],
)
EOF
printf '#!/bin/sh\nexit 0\n' > "$MOCK_DIR/cargo_bazel/cargo-bazel"
chmod +x "$MOCK_DIR/cargo_bazel/cargo-bazel"

mkdir -p "$MOCK_DIR/rust_tools/bin" "$MOCK_DIR/rust_tools/lib/rustlib/${RUST_TRIPLE}/lib"
ln -sf /usr/bin/rustc "$MOCK_DIR/rust_tools/bin/rustc"
ln -sf /usr/bin/rustdoc "$MOCK_DIR/rust_tools/bin/rustdoc"
for tool in cargo rustfmt clippy-driver cargo-clippy; do
    printf '#!/bin/sh\nexit 0\n' > "$MOCK_DIR/rust_tools/bin/$tool"
    chmod +x "$MOCK_DIR/rust_tools/bin/$tool"
done
if [ -d "/usr/lib/rustlib/${RUST_TRIPLE}/lib" ]; then
    cp -a /usr/lib/rustlib/${RUST_TRIPLE}/lib/* "$MOCK_DIR/rust_tools/lib/rustlib/${RUST_TRIPLE}/lib/" || true
fi
cat > "$MOCK_DIR/rust_tools/MODULE.bazel" << 'EOF'
module(name = "rust_tools")
EOF
cat > "$MOCK_DIR/rust_tools/BUILD.bazel" << EOF
load("@rules_rust//rust:toolchain.bzl", "rust_stdlib_filegroup", "rust_toolchain", "rustfmt_toolchain")

package(default_visibility = ["//visibility:public"])

filegroup(name = "rustc", srcs = ["bin/rustc"])
filegroup(
    name = "rustc_lib",
    srcs = glob([
        "bin/*.so",
        "lib/*.so*",
        "lib/rustlib/${RUST_TRIPLE}/codegen-backends/*.so",
        "lib/rustlib/${RUST_TRIPLE}/bin/rust-lld",
        "lib/rustlib/${RUST_TRIPLE}/lib/*.so*",
    ], allow_empty = True),
)
filegroup(name = "rustdoc", srcs = ["bin/rustdoc"])
filegroup(name = "cargo", srcs = ["bin/cargo"])
filegroup(name = "rustfmt_bin", srcs = ["bin/rustfmt"])
filegroup(name = "clippy_driver_bin", srcs = ["bin/clippy-driver"])
filegroup(name = "cargo_clippy_bin", srcs = ["bin/cargo-clippy"])

rust_stdlib_filegroup(
    name = "rust_std-${RUST_TRIPLE}",
    srcs = glob([
        "lib/rustlib/${RUST_TRIPLE}/lib/*.rlib",
        "lib/rustlib/${RUST_TRIPLE}/lib/*.so*",
        "lib/rustlib/${RUST_TRIPLE}/lib/*.a",
        "lib/rustlib/${RUST_TRIPLE}/lib/self-contained/**",
    ], allow_empty = True),
)

alias(name = "rust_lib-${RUST_TRIPLE}", actual = "rust_std-${RUST_TRIPLE}")

rust_toolchain(
    name = "rust_toolchain",
    rust_doc = ":rustdoc",
    rust_std = ":rust_std-${RUST_TRIPLE}",
    rustc = ":rustc",
    rustfmt = ":rustfmt_bin",
    cargo = ":cargo",
    clippy_driver = ":clippy_driver_bin",
    cargo_clippy = ":cargo_clippy_bin",
    llvm_cov = None,
    llvm_profdata = None,
    rustc_lib = ":rustc_lib",
    allocator_library = "@rules_rust//ffi/cc/allocator_library",
    global_allocator_library = None,
    binary_ext = "",
    staticlib_ext = ".a",
    dylib_ext = ".so",
    stdlib_linkflags = ["-ldl", "-lpthread"],
    default_edition = "2021",
    exec_triple = "${RUST_TRIPLE}",
    target_triple = "${RUST_TRIPLE}",
)

toolchain(
    name = "toolchain",
    toolchain = ":rust_toolchain",
    toolchain_type = "@rules_rust//rust:toolchain",
)

rustfmt_toolchain(
    name = "rustfmt_toolchain",
    rustfmt = ":rustfmt_bin",
    rustc = ":rustc",
    rustc_lib = ":rustc_lib",
)

toolchain(
    name = "rustfmt_toolchain_decl",
    toolchain = ":rustfmt_toolchain",
    toolchain_type = "@rules_rust//rust/rustfmt:toolchain_type",
)
EOF

cd "$WORKDIR"

bazel --batch test //... \
    --noenable_workspace \
    --registry=file://"$MOCK_DIR" \
    --check_direct_dependencies=off \
    --@rules_rust//rust/settings:toolchain_generated_sysroot=false \
    --override_module=aspect_bazel_lib=/usr/share/bazel/tools/aspect_bazel_lib \
    --override_module=bazel_lib=/usr/share/bazel/tools/bazel_lib \
    --override_module=stardoc=/usr/share/bazel/tools/stardoc \
    --override_module=rules_proto_grpc=/usr/share/bazel/rules/proto_grpc \
    --override_module=rules_rust=/usr/share/bazel/rules/rust \
    --override_module=rules_shell=/usr/share/bazel/rules/shell \
    --override_module=aspect_rules_js="$MOCK_DIR/aspect_rules_js" \
    --override_module=protobuf="$MOCK_DIR/protobuf" \
    --override_module=apple_support="$MOCK_DIR/apple_support" \
    --override_module=buildozer="$MOCK_DIR/buildozer" \
    --override_module=zlib="$MOCK_DIR/zlib" \
    --override_repository=rules_rust~~rust~rust_toolchains="$MOCK_DIR/rust_tools" \
    --override_repository=rust_toolchains="$MOCK_DIR/rust_tools" \
    --override_repository=rules_rust~~rust_host_tools~rust_host_tools="$MOCK_DIR/rust_tools" \
    --override_repository=rust_host_tools="$MOCK_DIR/rust_tools" \
    --override_repository=rules_rust~~crate~cargo_bazel_bootstrap="$MOCK_DIR/cargo_bazel" \
    --override_repository=rules_rust~~cargo_bazel_bootstrap~cargo_bazel_bootstrap="$MOCK_DIR/cargo_bazel" \
    --override_repository=rules_rust~~i~rules_rust_tinyjson="$MOCK_DIR/tinyjson" \
    --override_repository=rules_rust_tinyjson="$MOCK_DIR/tinyjson" \
    --test_output=errors
