{
  description = "Burrow development shell and forge host configuration";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    flake-utils.url = "tarball+https://codeload.github.com/numtide/flake-utils/tar.gz/main";
    agenix = {
      url = "github:ryantm/agenix";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    disko = {
      url = "tarball+https://codeload.github.com/nix-community/disko/tar.gz/master";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    nsc-autoscaler = {
      url = "git+https://compatible.systems/conrad/nsc-autoscaler.git";
      inputs.nixpkgs.follows = "nixpkgs";
      inputs.flake-utils.follows = "flake-utils";
    };
    hcloud-upload-image-src = {
      url = "tarball+https://codeload.github.com/apricote/hcloud-upload-image/tar.gz/v1.3.0";
      flake = false;
    };
  };

  outputs = { self, nixpkgs, flake-utils, agenix, disko, nsc-autoscaler, hcloud-upload-image-src }:
    let
      supportedSystems = [
        "x86_64-linux"
        "aarch64-linux"
        "x86_64-darwin"
        "aarch64-darwin"
      ];
    in
    (flake-utils.lib.eachSystem supportedSystems (system:
      let
        pkgs = import nixpkgs {
          inherit system;
        };
        lib = pkgs.lib;
        bazelPkg =
          if lib.hasAttr "bazelisk" pkgs then
            pkgs.bazelisk
          else if lib.hasAttr "bazel_9" pkgs then
            pkgs.bazel_9
          else if lib.hasAttr "bazel" pkgs then
            pkgs.bazel
          else
            pkgs.bazel_7;
        buildifierPkg =
          if lib.hasAttr "buildifier" pkgs then
            pkgs.buildifier
          else
            pkgs.bazel-buildtools;
        nodejsPkg =
          if lib.hasAttr "nodejs_22" pkgs then
            pkgs.nodejs_22
          else if lib.hasAttr "nodejs_24" pkgs then
            pkgs.nodejs_24
          else if lib.hasAttr "nodejs" pkgs then
            pkgs.nodejs
          else
            pkgs.nodejs_20;
        python3WithCrypto = pkgs.python3.withPackages (pythonPackages: [
          pythonPackages.cryptography
        ]);
        optionalPackage = name: lib.optional (lib.hasAttr name pkgs) (lib.getAttr name pkgs);
        googleKmsPkcs11Package =
          if pkgs.stdenv.hostPlatform.isx86_64 && pkgs.stdenv.isLinux then
            let
              version = "1.9";
            in
            pkgs.stdenv.mkDerivation {
              pname = "google-kms-pkcs11";
              inherit version;
              src = pkgs.fetchurl {
                url = "https://github.com/GoogleCloudPlatform/kms-integrations/releases/download/pkcs11-v${version}/libkmsp11-${version}-linux-amd64.tar.gz";
                sha256 = "sha256-U5f5ZQc81dHixD5RSPEC8xp8g1kC+X60HHycDxuHakA=";
              };
              nativeBuildInputs = [ pkgs.autoPatchelfHook ];
              buildInputs = [ pkgs.stdenv.cc.cc.lib ];
              installPhase = ''
                runHook preInstall
                install -Dm755 libkmsp11.so "$out/lib/libkmsp11.so"
                install -Dm644 kmsp11.h "$out/include/kmsp11.h"
                install -Dm644 LICENSE "$out/share/licenses/google-kms-pkcs11/LICENSE"
                mkdir -p "$out/bin"
                cat > "$out/bin/google-kms-pkcs11-module" <<EOF
#!/usr/bin/env sh
printf '%s\n' "$out/lib/libkmsp11.so"
EOF
                chmod 755 "$out/bin/google-kms-pkcs11-module"
                runHook postInstall
              '';
              meta = with lib; {
                description = "Google Cloud KMS PKCS#11 library";
                homepage = "https://github.com/GoogleCloudPlatform/kms-integrations";
                license = licenses.asl20;
                platforms = [ "x86_64-linux" ];
              };
            }
          else
            null;
        rcodesignPkcs11Package =
          if pkgs ? rcodesign then
            pkgs.rcodesign.overrideAttrs (old: {
              pname = "rcodesign-pkcs11";
              patches = (old.patches or [ ]) ++ [
                ./patches/rcodesign-pkcs11-tool.patch
              ];
              nativeBuildInputs = (old.nativeBuildInputs or [ ]) ++ [ pkgs.makeWrapper ];
              postInstall = (old.postInstall or "") + ''
                wrapProgram "$out/bin/rcodesign" \
                  --prefix PATH : ${lib.makeBinPath [ pkgs.opensc pkgs.openssl ]} \
                  --set-default BURROW_OPENSSL_MODULES ${pkgs.pkcs11-provider}/lib/ossl-modules
              '';
              passthru = (old.passthru or { }) // {
                isBurrowPkcs11Fork = true;
              };
              meta = (old.meta or { }) // {
                description = "rcodesign with Burrow PKCS#11 signing support";
              };
            })
          else
            null;
        commonPackages = with pkgs; [
          cargo
          rustc
          rustfmt
          clippy
          bazelPkg
          buildifierPkg
          protobuf
          pkg-config
          sqlite
          git
          openssh
          age
          opentofu
          curl
          jq
          nodejsPkg
          python3WithCrypto
          openssl
          rsync
          zip
          unzip
        ] ++ optionalPackage "google-cloud-sdk"
          ++ optionalPackage "awscli2"
          ++ optionalPackage "attic-client"
          ++ optionalPackage "opensc"
          ++ optionalPackage "pkcs11-provider"
          ++ lib.optional (googleKmsPkcs11Package != null) googleKmsPkcs11Package
          ++ lib.optional (rcodesignPkcs11Package != null) rcodesignPkcs11Package;
        linuxRepositoryPackages = lib.optionals pkgs.stdenv.isLinux (
          (with pkgs; [
            dpkg
            rpm
            createrepo_c
            pacman
            fakeroot
            zstd
          ])
          ++ optionalPackage "cargo-generate-rpm"
        );
        packageRepositoryPackages =
          linuxRepositoryPackages;
        linuxGtkNativePackages = lib.optionals pkgs.stdenv.isLinux (with pkgs; [
          meson
          ninja
          cmake
          clang
          gettext
          desktop-file-utils
        ]);
        linuxGtkBuildInputs = lib.optionals pkgs.stdenv.isLinux (with pkgs; [
          gtk4
          libadwaita
          glib
          openssl
        ]);
        gtkShellPackages = with pkgs; [
          cargo
          rustc
          rustfmt
          clippy
          protobuf
          pkg-config
          sqlite
          git
        ];
        nscPkg =
          if pkgs.stdenv.isLinux || pkgs.stdenv.isDarwin then
            let
              version = "0.0.520";
              osName =
                if pkgs.stdenv.isLinux then
                  "linux"
                else if pkgs.stdenv.isDarwin then
                  "darwin"
                else
                  throw "nsc: unsupported host OS ${pkgs.stdenv.hostPlatform.system}";
              archInfo =
                if pkgs.stdenv.hostPlatform.isx86_64 then
                  {
                    arch = "amd64";
                    hash =
                      if pkgs.stdenv.isLinux then
                        "sha256-Fqy6baIGQOGwbMCYHECOy5GcJg23xSs8XaZRfia5aHE="
                      else
                        "sha256-dCOr3mjAAhaByXX4yUr0dXZan8Mx8nbfggUemK7psbM=";
                  }
                else if pkgs.stdenv.hostPlatform.isAarch64 then
                  {
                    arch = "arm64";
                    hash =
                      if pkgs.stdenv.isLinux then
                        "sha256-Vv+UUd0BpcxwEg2dCsGJ/7lFOcXrl9yNwHDoHrgivKY="
                      else
                        "sha256-ASVXJhNwuWQ6T5nGTclZkv+5pPDPD/Q4i4nyAjVw2Gw=";
                  }
                else
                  throw "nsc: unsupported host platform ${pkgs.stdenv.hostPlatform.system}";
              src = pkgs.fetchurl {
                url = "https://github.com/namespacelabs/foundation/releases/download/v${version}/nsc_${version}_${osName}_${archInfo.arch}.tar.gz";
                sha256 = archInfo.hash;
              };
            in
            pkgs.stdenvNoCC.mkDerivation {
              pname = "nsc";
              inherit version src;
              meta.mainProgram = "nsc";
              dontConfigure = true;
              dontBuild = true;
              unpackPhase = ''
                tar -xzf "$src"
              '';
              installPhase = ''
                install -d "$out/bin"
                install -m 0555 nsc "$out/bin/nsc"
                install -m 0555 docker-credential-nsc "$out/bin/docker-credential-nsc"
                install -m 0555 bazel-credential-nsc "$out/bin/bazel-credential-nsc"
              '';
            }
          else
            null;
        hcloudUploadImagePkg = pkgs.buildGoModule {
          pname = "hcloud-upload-image";
          version = "1.3.0";
          src = hcloud-upload-image-src;
          vendorHash = "sha256-IdOAUBPg0CEuHd2rdc7jOlw0XtnAhr3PVPJbnFs2+x4=";
          subPackages = [ "." ];
          env.GOWORK = "off";
          ldflags = [
            "-s"
            "-w"
          ];
        };
        forgejoNscSrc = lib.cleanSourceWith {
          src = ./services/forgejo-nsc;
          filter = path: type:
            let
              p = toString path;
              name = builtins.baseNameOf path;
              hasDir = dir: lib.hasInfix "/${dir}/" p || lib.hasSuffix "/${dir}" p;
            in
            !(hasDir ".git" || hasDir "vendor" || hasDir "node_modules" || name == "result");
        };
        forgejoNscDispatcher = pkgs.buildGoModule {
          pname = "forgejo-nsc-dispatcher";
          version = "0.1.0";
          src = forgejoNscSrc;
          subPackages = [ "./cmd/forgejo-nsc-dispatcher" ];
          vendorHash = "sha256-Kpr+5Q7Dy4JiLuJVZbFeJAzLR7PLPYxhtJqfxMEytcs=";
        };
        forgejoNscAutoscaler = pkgs.buildGoModule {
          pname = "forgejo-nsc-autoscaler";
          version = "0.1.0";
          src = forgejoNscSrc;
          subPackages = [ "./cmd/forgejo-nsc-autoscaler" ];
          vendorHash = "sha256-Kpr+5Q7Dy4JiLuJVZbFeJAzLR7PLPYxhtJqfxMEytcs=";
        };
        burrowSrc = lib.cleanSourceWith {
          src = ./.;
          filter = path: type:
            let
              p = toString path;
              name = builtins.baseNameOf path;
              hasDir = dir: lib.hasInfix "/${dir}/" p || lib.hasSuffix "/${dir}" p;
            in
            !(hasDir ".git" || hasDir "target" || hasDir "node_modules" || name == "result");
        };
        burrowPkg = pkgs.rustPlatform.buildRustPackage {
          pname = "burrow";
          version = "0.1.0";
          src = burrowSrc;
          cargoLock = {
            lockFile = ./Cargo.lock;
            outputHashes = {
              "tracing-oslog-0.1.2" = "sha256-DjJDiPCTn43zJmmOfuRnyti8iQf9qoXICMKIx4bAG3I=";
            };
          };
          cargoBuildFlags = [
            "-p"
            "burrow"
            "--bin"
            "burrow"
          ];
          nativeBuildInputs = [ pkgs.protobuf ];
          meta.mainProgram = "burrow";
        };
        gtkDevShell = pkgs.mkShell {
          packages = gtkShellPackages ++ linuxGtkNativePackages;
          buildInputs = linuxGtkBuildInputs;
        };
      in
      {
        devShells.default = pkgs.mkShell {
          packages =
            commonPackages
            ++ linuxGtkNativePackages
            ++ [
              hcloudUploadImagePkg
              forgejoNscDispatcher
              forgejoNscAutoscaler
            ]
            ++ lib.optionals (nscPkg != null) [ nscPkg ];
          buildInputs = linuxGtkBuildInputs;
        };

        devShells.gtk = gtkDevShell;

        devShells.ci = pkgs.mkShell {
          packages =
            commonPackages
            ++ packageRepositoryPackages
            ++ [
              hcloudUploadImagePkg
            ]
            ++ lib.optionals (nscPkg != null) [ nscPkg ];
        };

        formatter = pkgs.nixpkgs-fmt;

        packages =
          {
            age = pkgs.age;
            agenix = agenix.packages.${system}.agenix;
            burrow = burrowPkg;
            hcloud-upload-image = hcloudUploadImagePkg;
            forgejo-nsc-dispatcher = forgejoNscDispatcher;
            forgejo-nsc-autoscaler = forgejoNscAutoscaler;
          }
          // lib.optionalAttrs (nscPkg != null) { nsc = nscPkg; }
          // lib.optionalAttrs (googleKmsPkcs11Package != null) { google-kms-pkcs11 = googleKmsPkcs11Package; }
          // lib.optionalAttrs (rcodesignPkcs11Package != null) { rcodesign-pkcs11 = rcodesignPkcs11Package; };
      }))
    // {
      nixosModules.burrow-forge = import ./nixos/modules/burrow-forge.nix;
      nixosModules.burrow-forge-runner = import ./nixos/modules/burrow-forge-runner.nix;
      nixosModules.burrow-forgejo-nsc = nsc-autoscaler.nixosModules.default;
      nixosModules.burrow-authentik = import ./nixos/modules/burrow-authentik.nix;
      nixosModules.burrow-garage = import ./nixos/modules/burrow-garage.nix;
      nixosModules.burrow-headscale = import ./nixos/modules/burrow-headscale.nix;
      nixosModules.burrow-nix-cache = import ./nixos/modules/burrow-nix-cache.nix;
      nixosModules.burrow-observability = import ./nixos/modules/burrow-observability.nix;
      nixosModules.burrow-zulip = import ./nixos/modules/burrow-zulip.nix;
      nixosModules.burrow-openbao = import ./nixos/modules/burrow-openbao.nix;
      nixosModules.burrow-jitsi = import ./nixos/modules/burrow-jitsi.nix;
      nixosConfigurations.burrow-forge = nixpkgs.lib.nixosSystem {
        system = "x86_64-linux";
        specialArgs = {
          inherit self;
        };
        modules = [
          agenix.nixosModules.default
          disko.nixosModules.disko
          ./nixos/hosts/burrow-forge/default.nix
        ];
      };

      images = {
        burrow-forge-raw = self.nixosConfigurations.burrow-forge.config.system.build.diskoImages;
      };
    };
}
