inputs @ {
  self,
  flake-utils,
  nixpkgs,
  kubenix,
  ...
}:
flake-utils.lib.eachDefaultSystem
(system: let
  pkgs = nixpkgs.legacyPackages.${system};
  inherit (pkgs) lib;
  deployScript = (pkgs.writeScriptBin "applyset-deploy.sh" (builtins.readFile ./applyset-deploy.sh)).overrideAttrs (old: {
    buildCommand = "${old.buildCommand}\npatchShebangs $out";
  });

  mkKubernetes = name: module: namespace:
    (kubenix.evalModules.${system} {
      specialArgs = {
        inherit namespace system self;
        inherit (inputs) nixhelm blog dns nixpkgs;
        inherit (self) globals;

        utils = import ./utils.nix {
          inherit pkgs self;
          inherit (inputs) nixpkgs nixng nix-snapshotter;
          inherit (self) globals;
        };
      };

      module = {kubenix, ...}: {
        imports = [
          kubenix.modules.k8s
          kubenix.modules.helm
          ./modules
          module
        ];

        config = {
          kubenix.project = name;
          kubernetes.namespace = namespace;
        };
      };
    })
    .config
    .kubernetes;

  mkManifest = name: {
    module,
    namespace,
  }: {
    name = "${name}-manifest";
    value = (mkKubernetes name module namespace).result;
  };

  mkDeployApp = name: {
    module,
    namespace,
  }: let
    kubernetes = mkKubernetes name module namespace;
    kubeconfig = kubernetes.kubeconfig or "";
    result = kubernetes.result or "";

    wrappedDeployScript =
      pkgs.symlinkJoin
      {
        name = "applyset-deploy.sh";
        paths = [deployScript pkgs.vals pkgs.kubectl pkgs.gettext];
        buildInputs = [pkgs.makeWrapper];
        passthru.manifest = result;
        meta.mainProgram = "applyset-deploy.sh";

        postBuild = let
          # HACK: create normal way of checking if server runs k8s
          k8sMachines = builtins.attrNames self.globals.nodeLabels;
          k8sServerNames = builtins.concatStringsSep " " k8sMachines;
        in
          /*
          bash
          */
          ''
            wrapProgram $out/bin/applyset-deploy.sh \
              --suffix PATH : "$out/bin" \
              --run 'export KUBECONFIG=''${KUBECONFIG:-${toString kubeconfig}}' \
              --set MANIFEST '${result}' \
              --set NAME '${name}' \
              --set NAMESPACE '${namespace}' \
              --set SERVERS '${k8sServerNames}' \
              --set DYFF '${lib.getExe pkgs.dyff}' \
              --set GCROOTDIR '/nix/var/nix/gcroots/kubernetes-manifests'
          '';
      };
  in {
    name = "${name}-deploy";
    value = wrappedDeployScript;
  };

  deployments = import ./deployments.nix;
in {
  packages = pkgs.lib.mergeAttrs (pkgs.lib.mapAttrs' mkDeployApp deployments) (pkgs.lib.mapAttrs' mkManifest deployments);
})