# SPDX-FileCopyrightText: 2022-2024 Sarah Vaupel <sarah.vaupel@uniworx.de>, Gregor Kleen <gregor@kleen.consulting>, Steffen Jost <jost@cip.ifi.lmu.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later

{ inputs, backendSource, gitRevision ? null, ... }: final: prev:

with prev.lib;

let
  haskellInputs = ["encoding" "memcached-binary" "conduit-resumablesink" "HaskellNet-SSL" "ldap-client" "serversession" "xss-sanitize" "colonnade" "minio-hs" "cryptoids" "zip-stream" "yesod" "cryptonite" "esqueleto"];
in {
  uniworx = final.haskell-nix.stackProject {
    src = prev.stdenv.mkDerivation {
      name = "uniworx-src";
      src = backendSource;

      phases = ["unpackPhase" "patchPhase" "installPhase"];

      patchPhase = ''
        substitute stack-flake.yaml stack.yaml \
          ${concatMapStringsSep " \\\n" (pkgName: "--replace @${pkgName}@ ${inputs."${pkgName}"}") haskellInputs}
      '';

      installPhase = ''
        mkdir -p $out
        cp -pr --reflink=auto ./. $out
      '';
    };
    compiler-nix-name = "ghc94";
    # stack-sha256 = "1n7z294ldv2rjkfj1vs3kqmnbp34m2scrmyrp5kwmga9vp86fd9z"; # produces errors gregor does not understand :(
    modules = [
      {
        packages = {
          encoding.src = inputs.encoding;
          memcached-binary.src = inputs.memcached-binary;
          conduit-resumablesink.src = inputs.conduit-resumablesink;
          HaskellNet-SSL.src = inputs.HaskellNet-SSL;
          ldap-client.src = inputs.ldap-client;
          serversession.src = "${inputs.serversession}/serversession";
          serversession-backend-acid-state.src = "${inputs.serversession}/serversession-backend-acid-state";
          xss-sanitize.src = inputs.xss-sanitize;
          colonnade.src = "${inputs.colonnade}/colonnade";
          minio-hs.src = inputs.minio-hs;
          cryptoids-class.src = "${inputs.cryptoids}/cryptoids-class";
          cryptoids-types.src = "${inputs.cryptoids}/cryptoids-types";
          cryptoids.src = "${inputs.cryptoids}/cryptoids";
          filepath-crypto.src = "${inputs.cryptoids}/filepath-crypto";
          uuid-crypto.src = "${inputs.cryptoids}/uuid-crypto";
          zip-stream.src = inputs.zip-stream;
          yesod.src = "${inputs.yesod}/yesod";
          yesod-core.src = "${inputs.yesod}/yesod-core";
          yesod-static.src = "${inputs.yesod}/yesod-static";
          yesod-persistent.src = "${inputs.yesod}/yesod-persistent";
          yesod-form.src = "${inputs.yesod}/yesod-form";
          yesod-auth.src = "${inputs.yesod}/yesod-auth";
          yesod-test.src = "${inputs.yesod}/yesod-test";
          cryptonite.src = inputs.cryptonite;
          esqueleto.src = inputs.esqueleto;
        };
      }
      {
        packages.uniworx = {
          postUnpack = ''
            ${final.xorg.lndir}/bin/lndir -silent ${prev.uniworxFrontend} $sourceRoot
            chmod a+w -R $sourceRoot
          '';
          preBuild = ''
            export TZDIR=${final.tzdata}/share/zoneinfo
            ${optionalString (gitRevision != null) ''
              export GIT_REVISION=${gitRevision}
            ''}
          '';
          components.library.build-tools = with final.pkgs; [ llvm_9 ];
          components.exes.uniworx.build-tools = with final.pkgs; [ llvm_9 ];
          components.exes.uniworxdb.build-tools = with final.pkgs; [ llvm_9 ];
          components.exes.uniworxload.build-tools = with final.pkgs; [ llvm_9 ];          
          components.tests.yesod = {
            build-tools = with final.pkgs; [ llvm_9 final.uniworx.hsPkgs.hspec-discover ];
            testWrapper =
              let
                testWrapper = prev.writeScript "test-wrapper" (import ../develop.nix { inherit prev; pkgs = final; doDevelopEnv = false; } "$@");
                testWrapperWrapped = prev.runCommand "test-wrapper" { buildInputs = [final.makeWrapper]; } ''
                  makeWrapper ${testWrapper} $out \
                    --prefix PATH : ${final.postgresql_12}/bin \
                    --prefix PATH : ${final.minio}/bin \
                    --prefix PATH : ${final.memcached}/bin
                '';
              in singleton (toString testWrapperWrapped);
          };
          components.tests.hlint.build-tools = with final.pkgs; [ llvm_9 final.uniworx.hsPkgs.hlint-test ];
        };
      }
    ];
  };
}
