{
  lib,
  stdenv,
  fetchFromGitHub,
  git,
  bun,
  nodejs,
  ruby_3_2,
  bundlerEnv,
  logDir ? "/var/log/ds-fr",
  dataDir ? "/var/lib/ds-fr",
  initialDeploymentDate ? "17941030",
}:

let
  inherit (lib) getExe;

  # Head of the DGNum repo
  dgn-id = "f270f1cdd09e643a9c666c94df1841234430de49";

  pname = "ds-fr";
  meta = import ./meta.nix;

  inherit (meta) version;

  src = fetchFromGitHub {
    owner = "demarches-simplifiees";
    repo = "demarches-simplifiees.fr";
    rev = version;
    hash = meta.src-hash;
  };

  rubyEnv = bundlerEnv {
    name = "env-${pname}";
    gemdir = ./rubyEnv;
    ruby = ruby_3_2;
    gemset = (import ./rubyEnv/gemset.nix) // {
      bundler = {
        groups = [ "default" ];
        platforms = [ ];
        source = {
          remotes = [ "https://rubygems.org" ];
          sha256 = "deeQ3fNwcSiGSO/yeB2yoTniRq2gHW8WueprXoPX6Jk=";
          type = "gem";
        };
        version = "2.3.11";
      };
    };
  };

  node_modules = stdenv.mkDerivation {
    pname = "${pname}-node_modules";
    inherit src version;

    impureEnvVars = lib.fetchers.proxyImpureEnvVars ++ [
      "GIT_PROXY_COMMAND"
      "SOCKS_SERVER"
    ];

    nativeBuildInputs = [ bun ];

    dontConfigure = true;

    buildPhase = ''
      bun install --no-progress --frozen-lockfile --ignore-scripts 
      rm -r node_modules/.cache

      # Remove inconsistent file
      rm node_modules/.bin/grunt
    '';

    installPhase = ''
      mv node_modules $out
    '';

    dontFixup = true;

    outputHash = meta.deps-hash or lib.fakeHash;
    outputHashAlgo = "sha256";
    outputHashMode = "recursive";
  };

  dsModules = stdenv.mkDerivation {
    pname = "${pname}-modules";
    inherit src version;

    buildInputs = [ rubyEnv ];
    nativeBuildInputs = [
      bun
      nodejs
      rubyEnv.wrappedRuby
    ];

    RAILS_ENV = "production";
    NODE_ENV = "dev";

    patches = [
      # Disable functionnalities as we only precompile assets
      ./patches/build.patch
    ];

    postPatch = ''
      ${getExe git} apply -p1 < ${builtins.fetchurl "https://git.dgnum.eu/DGNum/demarches-normaliennes/commit/${dgn-id}.patch"}
    '';

    OTP_SECRET_KEY = "precompile_placeholder";
    SECRET_KEY_BASE = "precompile_placeholder";
    APP_HOST = "precompile_placeholder";

    buildPhase = ''
      cp -R ${node_modules} node_modules
      chmod u+w -R node_modules

      patchShebangs node_modules
      patchShebangs bin/

      bin/rake assets:precompile
    '';

    installPhase = ''
      mkdir -p $out/public
      cp -r public/* $out/public
    '';
  };
in
stdenv.mkDerivation {
  name = "demarches-simplifiees.fr-${version}";

  inherit src;

  buildInputs = [ rubyEnv ];
  propagatedBuildInputs = [ rubyEnv.wrappedRuby ];

  patches = [
    ./patches/replay_routing_engine_for_a_cloned_procedure.patch
    ./patches/smtp_settings.patch
    ./patches/garage.patch
  ];

  postPatch = ''
    ${getExe git} apply -p1 < ${builtins.fetchurl "https://git.dgnum.eu/DGNum/demarches-normaliennes/commit/${dgn-id}.patch"}
  '';

  buildPhase = ''
    rm -rf public
    ln -s ${dsModules}/public/ public

    patchShebangs bin/

    rm -rf log storage
    ln -s ${logDir} log
    ln -s ${dataDir}/tmp tmp
    ln -s ${dataDir}/storage storage

    for f in $(ls lib/tasks/deployment/); do
      [[ ! ${initialDeploymentDate} < $f ]] \
        && rm lib/tasks/deployment/$f;
    done;

    echo "Removed unused data migrations"
  '';

  installPhase = ''
    mkdir -p $out
    cp -r * $out/
  '';

  passthru = {
    inherit rubyEnv;
    ruby = rubyEnv.wrappedRuby;
  };

  meta = with lib; {
    description = "Dématérialiser et simplifier les démarches administratives";
    homepage = "https://github.com/demarches-simplifiees/demarches-simplifiees.fr";
    license = licenses.agpl3Only;
    maintainers = with maintainers; [ thubrecht ];
  };
}