#!/usr/bin/env -S nix-build
{ pkgs ? import <nixpkgs> {},
  stdenv ? pkgs.stdenv,
  lib ? pkgs.lib,
  ldc ? null,
  dcompiler ? pkgs.ldc,
  dub ? pkgs.dub
}:
assert dcompiler != null;
with (
  assert dcompiler != null;
  with lib;
  let
    # Filter function to remove the .dub package folder from src
    filterDub = name: type: let baseName = baseNameOf (toString name); in ! (
      type == "directory" && baseName == ".dub"
    );
    targetOf = package: "${package.targetPath or "."}/${package.targetName or package.name}";
    # Remove reference to build tools and library sources
    disallowedReferences = deps: [ dcompiler dub ];
    removeExpr = refs: ''remove-references-to ${lib.concatMapStrings (ref: " -t ${ref}") refs}'';
  in {
    mkDubDerivation = lib.makeOverridable ({
      src,
      nativeBuildInputs ? [],
      dubJSON ? src + "/dub.json",
      passthru ? {},
      package ? lib.importJSON dubJSON,
      ...
    } @ attrs: stdenv.mkDerivation (attrs // {
      pname = package.name;
      nativeBuildInputs = [ dcompiler dub pkgs.removeReferencesTo ] ++ nativeBuildInputs;
      disallowedReferences = disallowedReferences deps;
      passthru = passthru // {
        inherit dub dcompiler pkgs;
      };
      src = lib.cleanSourceWith {
        filter = filterDub;
        src = lib.cleanSource src;
      };
      preFixup = ''
        find $out/bin -type f -exec ${removeExpr (disallowedReferences deps)} '{}' + || true
      '';
      buildPhase = ''
        runHook preBuild
        export HOME=$PWD
        for dc_ in dmd ldmd2 gdmd; do
          echo "- check for D compiler $dc_"
          dc=$(type -P $dc_ || echo "")
          if [ ! "$dc" == "" ]; then
            break
          fi
        done
        if [ "$dc" == "" ]; then
          exit "Error: could not find D compiler"
        fi
        echo "$dc_ used as D compiler to build $pname"
        dub build --compiler=$dc --build=release --combined --skip-registry=all
        runHook postBuild
      '';
      checkPhase = ''
        runHook preCheck
        export HOME=$PWD
        dub test --combined --skip-registry=all
        runHook postCheck
      '';
      installPhase = ''
        runHook preInstall
        mkdir -p $out/bin
        cp -r "${targetOf package}" $out/bin
        runHook postInstall
      '';
      meta = lib.optionalAttrs (package ? description) {
        description = package.description;
      } // attrs.meta or {};
    } // lib.optionalAttrs (!(attrs ? version)) {
      # Use name from dub.json, unless pname and version are specified
      name = package.name;
    }));
  }
);
mkDubDerivation rec {
  name = "spine-${version}";
  version = "0.11.3";
  src = ./.;
  buildInputs = with pkgs; [
    nixFlakes
    rund
    dub
    ldc
    sqlite
  ];
  # buildPhase = [ ];
  installPhase = ''
    install -m755 -D spine $out/bin/spine
    echo "built $out/bin/spine"
  '';
  meta = with pkgs.lib; {
    homepage    = https://sisudoc.org;
    description = "a sisu like document parser";
    license     = licenses.agpl3Plus;
    platforms   = platforms.linux;
    maintainers = [ RalphAmissah ];
  };
}