{
  config,
  lib,
  pkgs,
  ...
}:
let
  inherit (lib)
    mkIf
    mkOption
    mkMerge
    types
    ;
  assertions = import ../assertions.nix { inherit lib; };

  cfg = config.services.podman;

  podman-lib = import ./podman-lib.nix { inherit pkgs lib config; };

  createQuadletSource =
    name: buildDef:
    let
      quadlet = podman-lib.deepMerge {
        Build = {
          AuthFile = buildDef.authFile;
          Environment = buildDef.environment;
          File = buildDef.file;
          ImageTag = [ "homemanager/${name}" ] ++ buildDef.tags;
          Label = buildDef.labels // {
            "nix.home-manager.managed" = true;
          };
          PodmanArgs = buildDef.extraPodmanArgs;
          SetWorkingDirectory = buildDef.workingDirectory;
          TLSVerify = buildDef.tlsVerify;
        };
        Install = {
          WantedBy = lib.optionals buildDef.autoStart [
            "default.target"
            "multi-user.target"
          ];
        };
        Service = {
          TimeoutStartSec = 300;
          RemainAfterExit = "yes";
        };
        Unit = {
          Description = buildDef.description;
        };
      } buildDef.extraConfig;
    in
    {
      attrs = quadlet;
      text = ''
        # Automatically generated by home-manager for podman build configuration
        # DO NOT EDIT THIS FILE DIRECTLY
        #
        # ${name}.build
        ${podman-lib.toQuadletIni quadlet}
      '';
    };

  toQuadletInternal =
    name: buildDef:
    let
      src = createQuadletSource name buildDef;
    in
    {
      assertions = podman-lib.buildConfigAsserts name buildDef.extraConfig;
      serviceName = "podman-${name}"; # generated service name: 'podman-<name>-build.service
      source = podman-lib.removeBlankLines src.text;
      resourceType = "build";
    };

  buildDefinitionType = types.submodule (
    { name, ... }:
    {
      options = {

        autoStart = mkOption {
          type = types.bool;
          default = true;
          description = "Whether to start the build on boot. Requires user lingering.";
        };

        authFile = mkOption {
          type = with types; nullOr path;
          default = null;
          description = "Path of the authentication file.";
        };

        description = mkOption {
          type = with types; nullOr str;
          default = "Service for build ${name}";
          defaultText = "Service for build \${name}";
          example = "My Build";
          description = "The description of the build.";
        };

        environment = mkOption {
          type = podman-lib.primitiveAttrs;
          default = { };
          example = {
            VAR1 = "0:100";
            VAR2 = true;
            VAR3 = 5;
          };
          description = "Environment variables to set in the build.";
        };

        extraConfig = mkOption {
          type = podman-lib.extraConfigType;
          default = { };
          example = {
            Build = {
              Arch = "aarch64";
            };
            Service = {
              TimeoutStartSec = 15;
            };
          };
          description = "INI sections and values to populate the Build Quadlet.";
        };

        extraPodmanArgs = mkOption {
          type = types.listOf types.str;
          default = [ ];
          example = [ "--retries 5" ];
          description = "Extra arguments to pass to the podman build command.";
        };

        file = mkOption {
          type = types.str;
          example = lib.literalExpression ''
            `"xdg.configFile."containerfiles/my-img/Containerfile"`
            or
            `"https://github.com/.../my-img/Containerfile"`
          '';
          description = "Path to a Containerfile which contains instructions to build the image.";
        };

        tags = mkOption {
          type = with types; listOf str;
          default = [ ];
          description = ''
            Name associated with the build.
            First tag will always be "homemanager/<name>".
          '';
        };

        labels = mkOption {
          type = with types; attrsOf str;
          default = { };
          example = {
            app = "myapp";
            some-label = "somelabel";
          };
          description = "The labels to apply to the build.";
        };

        tlsVerify = mkOption {
          type = types.bool;
          default = true;
          description = "Require HTTPS and verification of certificates when contacting registries.";
        };

        workingDirectory = mkOption {
          type = with types; nullOr path;
          default = null;
          description = "WorkingDirectory of the systemd unit file.";
        };
      };
    }
  );
in
{
  options.services.podman.builds = mkOption {
    type = types.attrsOf buildDefinitionType;
    default = { };
    description = "Defines Podman build quadlet configurations.";
  };

  config =
    let
      buildQuadlets = lib.mapAttrsToList toQuadletInternal cfg.builds;
    in
    mkIf cfg.enable (mkMerge [
      {
        assertions = [
          (assertions.assertPlatform "services.podman.builds" config pkgs lib.platforms.linux)
        ];
      }
      (mkIf pkgs.stdenv.hostPlatform.isLinux {
        services.podman.internal.quadletDefinitions = buildQuadlets;
        assertions = lib.flatten (map (build: build.assertions) buildQuadlets);

        xdg.configFile."podman/images.manifest".text = podman-lib.generateManifestText buildQuadlets;
      })
    ]);
}
