{ writeText, intelPackages, nodes, nosv, clangOmpss2Nodes, strace }:

let
  hello_cpp = writeText "hello.cpp" ''
    #include <cstdio>
    #include <sycl/sycl.hpp>

    int main(int argc, char** argv) try {
        sycl::queue queue;

        std::cout << "Running on: "
                  << queue.get_device().get_info<sycl::info::device::name>()
                  << std::endl;

        #pragma oss task
        queue.submit([&] (sycl::handler& cgh) {
            auto os = sycl::stream{128, 128, cgh};
            cgh.single_task<class hello_world>([=]() {
                os << "Hello World! (on device)\n";
            });
        }).wait();

        return 0;
    } catch (sycl::exception &e) {
        std::cout << "SYCL exception: " << e.what() << std::endl;
        return 0; // we expect to fail since no devices should be available;
    }

  '';
in

intelPackages.stdenv.mkDerivation {
  version = "0.0.1";
  name = "hello-syclompss";

  src = hello_cpp;

  nativeBuildInputs = [
    strace
    nodes
    nosv
  ];

  dontUnpack = true;
  dontConfigure = true;

  # NODES requires access to /sys/devices to request NUMA information. It will
  # fail to run otherwise, so we disable the sandbox for this test.
  __noChroot = true;

  env.NODES_HOME = nodes;

  NIX_DEBUG = 0;
  buildPhase = ''
    cp $src hello.cpp
    set -x
    echo CXX=$CXX
    echo NODES_HOME=$NODES_HOME
    command -v $CXX

    icpx -Wno-deprecated-declarations -fsycl \
        -fsycl-host-compiler=${clangOmpss2Nodes.forIcpx}/bin/clang++ \
        -fsycl-host-compiler-options='-Wno-deprecated-declarations -fompss-2=libnodes' \
        -lnodes -lnosv \
        $NODES_HOME/lib/nodes-main-wrapper.o \
        hello.cpp -o hello

    ./hello
    set +x
  '';

  installPhase = ''
    touch $out
  '';
}
