with import <nixpkgs> {};

let h2-lwt = ocamlPackages.buildDunePackage rec {
      pname = "h2-lwt";
      version = "0.12.0";
      src = pkgs.fetchurl {
        url = "https://github.com/anmonteiro/ocaml-h2/releases/download/0.12.0/h2-0.12.0.tbz";
        sha256 = "sha256-NuQLET2Q6jg2GajHvZk/hmExw8XZV2GbaEnrMq+MU8Y=";
      };
      propagatedBuildInputs = with pkgs; [
        h2
        ocamlPackages.faraday-async
        ocamlPackages.gluten-lwt
        ocamlPackages.gluten-async
      ];
    };

    h2-lwt-unix = ocamlPackages.buildDunePackage rec {
      pname = "h2-lwt-unix";
      version = "0.12.0";
      src = pkgs.fetchurl {
        url = "https://github.com/anmonteiro/ocaml-h2/releases/download/0.12.0/h2-0.12.0.tbz";
        sha256 = "sha256-NuQLET2Q6jg2GajHvZk/hmExw8XZV2GbaEnrMq+MU8Y=";
      };
      propagatedBuildInputs = with pkgs; [
        h2-lwt
        ocamlPackages.faraday-lwt-unix
        ocamlPackages.gluten-lwt-unix
      ];
    };

    h2 = ocamlPackages.buildDunePackage rec {
      pname = "h2";
      version = "0.12.0";
      src = pkgs.fetchurl {
        url = "https://github.com/anmonteiro/ocaml-h2/releases/download/0.12.0/h2-0.12.0.tbz";
        sha256 = "sha256-NuQLET2Q6jg2GajHvZk/hmExw8XZV2GbaEnrMq+MU8Y=";
      };
      propagatedBuildInputs = with pkgs; [
        ocamlPackages.base64
        ocamlPackages.angstrom
        ocamlPackages.faraday
        ocamlPackages.bigstringaf
        ocamlPackages.psq
        ocamlPackages.hpack
        ocamlPackages.httpun-types
        ocamlPackages.alcotest
        ocamlPackages.yojson
        ocamlPackages.hex
      ];
    };

    grpc-src = pkgs.fetchFromGitHub {
      owner = "dialohq";
      repo = "ocaml-grpc";
      rev = "0.2.0";
      sha256 = "sha256-YARAm3EVTbptAoKA0lysJRYeKPaCaeWU6X9Lzkn+30E=";
    };

    grpc = ocamlPackages.buildDunePackage rec {
      pname = "grpc";
      version = "0.2.0";
      src = grpc-src;
      propagatedBuildInputs = with pkgs; [
        ocamlPackages.uri
        h2
        ocamlPackages.ppx_deriving
        ocamlPackages.ppxlib
      ];
    };

    grpc-lwt = ocamlPackages.buildDunePackage rec {
      pname = "grpc-lwt";
      version = "0.2.0";
      src = grpc-src;
      propagatedBuildInputs = with pkgs; [
        ocamlPackages.stringext
        ocamlPackages.lwt
        grpc
      ];
    };

    tar = ocamlPackages.buildDunePackage rec {
      pname = "tar";
      version = "3.3.0";
      src = pkgs.fetchurl {
        url = "https://github.com/mirage/ocaml-tar/archive/refs/tags/v3.3.0.tar.gz";
        sha256 = "sha256-xxwUxq8G9G8LH8EedLaPAWNvxtpRFiWZyEv8YPgad+g=";
      };
      propagatedBuildInputs = with pkgs; [
        ocamlPackages.camlp-streams
        ocamlPackages.cstruct
        ocamlPackages.decompress
      ];
    };

    tar-unix = ocamlPackages.buildDunePackage rec {
      pname = "tar-unix";
      version = "3.3.0";
      src = pkgs.fetchurl {
        url = "https://github.com/mirage/ocaml-tar/archive/refs/tags/v3.3.0.tar.gz";
        sha256 = "sha256-xxwUxq8G9G8LH8EedLaPAWNvxtpRFiWZyEv8YPgad+g=";
      };
      propagatedBuildInputs = with pkgs; [
        ocamlPackages.lwt
        tar
      ];
    };

    tar-lwt-unix = tar-unix.overrideAttrs (_: {name = "tar-lwt-unix"; });

    elpe = ocamlPackages.buildDunePackage rec {
      pname = "elpe";
      version = "0.1.0";
      src = ./elpe;
      buildInputs = with pkgs; [
        ocamlPackages.ocaml-protoc-plugin
        ocamlPackages.findlib
        grpc-lwt
        h2-lwt-unix
        protobuf
      ];
      nativeBuildInputs = with pkgs; [
        ocamlPackages.ocaml-protoc-plugin
        protobuf
      ];
      propagatedBuildInputs = with pkgs; [
        ocaml
        ocamlPackages.ocaml-protoc-plugin
        ocamlPackages.findlib
        grpc-lwt
        h2-lwt-unix
      ];
      buildPhase = "dune build";
      postInstall = ''
        mkdir -p $out/bin
        cp _build/default/bin/elpe_bin.bc $out/bin/elpe
      '';
    };

    elpe_rs = (pkgs.callPackage ./Cargo.nix {
      inherit pkgs;
      defaultCrateOverrides = pkgs.defaultCrateOverrides // {
        elpe = attrs: {
          nativeBuildInputs = [ pkgs.protobuf ];
          PROTOC="${protobuf}/bin/protoc";
          propagatedBuildInputs = [ sequoia-sq ];
        };
      };
    }).workspaceMembers.elpe.build.overrideAttrs (attrs: {
      postInstall = "mv $out/bin/elpe $out/bin/elpe-server";
    });
in
clangStdenv.mkDerivation {
  name = "elpe";
  phases = [ "installPhase" "fixupPhase" ];
  propagatedBuildInputs = [ elpe elpe_rs sequoia-sq ];
  installPhase = "mkdir $out";
}