{ naersk
, fenix
, nodejs
, rustPlatform
, stdenv
, fetchFromGitHub
, buildEnv
, fetchCrate
, pkg-config
, gettext
, wasm-pack
, binaryen
, openssl
, postgresql
}:

let
  rust = fenix.complete.withComponents [
    "cargo"
    "rustc"
  ];
  naersk' = naersk.override {
    cargo = rust;
    rustc = rust;
  };
  rust-wasm = with fenix;
    combine [
      minimal.rustc
      minimal.cargo
      targets.wasm32-unknown-unknown.latest.rust-std
    ];
  naersk-wasm = naersk.override {
    cargo = rust-wasm;
    rustc = rust-wasm;
  };

  wasm-bindgen-cli = rustPlatform.buildRustPackage rec {
    pname = "wasm-bindgen-cli";
    version = "0.2.81";

    src = fetchCrate {
      inherit pname version;
      sha256 = "sha256-DUcY22b9+PD6RD53CwcoB+ynGulYTEYjkkonDNeLbGM=";
    };

    cargoSha256 = "sha256-mfVQ6rSzCgwYrN9WwydEpkm6k0E3302Kfs/LaGzRSHE=";

    nativeBuildInputs = [ pkg-config ];

    buildInputs = [ openssl ];

    checkInputs = [ nodejs ];

    # other tests require it to be ran in the wasm-bindgen monorepo
    cargoTestFlags = [ "--test=interface-types" ];
  };

  conv = fetchFromGitHub {
    owner = "DanielKeep";
    repo = "rust-conv";
    rev = "master";
    sha256 = "029xq9cabz3scbmd84b8qkrg0q7x6fm27ijq869lkpq8bwjxvcb6";
  };

  version = "0.7.2-1";

  src = stdenv.mkDerivation {
    pname = "plume-src";
    inherit version;
    src = fetchFromGitHub {
      owner = "Plume-org";
      repo = "Plume";
      # rev = version;
      rev = "620726cc2564ededb98af42c3c2e35407fcf1184";
      sha256 = "sha256-B8EAV61qdTBGn+vGQZlXjAaSkEPs8wr9ZH1Roq3CZZs=";
    };
    phases = [ "unpackPhase" "patchPhase" "installPhase" ];
    patches = [
      ./0001-cargo-update.patch
    ];
    postPatch = ''
      ln -s ${conv} rust-conv
    '';
    installPhase = "cp -ar . $out";
  };

  plume = naersk'.buildPackage {
    pname = "plume";
    inherit src version;

    nativeBuildInputs = [
      pkg-config
      gettext
      wasm-bindgen-cli
    ];
    buildInputs = [
      openssl
      postgresql
    ];
    overrideMain = oa: {
      installPhase = ''
        ${oa.installPhase}

        mkdir -p $out/share/plume
        cp -ar static $out/share/plume/
      '';
    };
  };

  plm = naersk'.buildPackage {
    pname = "plm";
    root = src;

    nativeBuildInputs = [
      pkg-config
    ];
    buildInputs = [
      openssl
      postgresql
    ];
    cargoBuildOptions = x: x ++ [ "--package=plume-cli" ];
  };

  plume-front = naersk-wasm.buildPackage {
    pname = "plume-front";
    root = src;
    nativeBuildInputs = [
      gettext
      wasm-pack
      wasm-bindgen-cli
      binaryen
    ];
    CARGO_BUILD_TARGET = "wasm32-unknown-unknown";
    cargoBuildOptions = x:
      x ++ [
        "--package=plume-front"
      ];
    copyLibs = true;
    overrideMain = _: {
      buildPhase = ''
        wasm-pack build --mode no-install --target web --release plume-front
      '';
      installPhase = ''
        mkdir -p $out/share/plume/static
        cp -a plume-front/pkg/*.{js,ts,wasm} $out/share/plume/static/
      '';
    };
  };
in
buildEnv {
  name = "plume-env";
  paths = [ plume plume-front plm ];
  passthru = { inherit plume plm; };
}
