{
  flake,
  config,
  pkgs,
  lib,
  ...
}:
let
  inherit (flake.config.people) user0;
  inherit (flake.config.services) instances;
  serviceCfg = flake.config.services.instances.mastodon;
  smtpCfg = flake.config.services.instances.smtp;
  hostCfg = flake.config.services.instances.web;
  host = serviceCfg.domains.url0;
  dns0 = instances.web.dns.provider0;
  dns0Path = "dns/${dns0}";
in
{
  # If you need to start fresh for some reason, run these to create the new Admin account:
  # sudo -u mastodon mastodon-tootctl accounts create nick --email=nick@localhost --confirmed --role=Owner
  # sudo -u mastodon mastodon-tootctl accounts approve nick

  # If you fuck up and lose the password, use this:
  # sudo mastodon-tootctl accounts modify --reset-password nick

  # If you really fuck up and name yourself wrong, use this shit
  # sudo mastodon-tootctl accounts modify username --remove-role

  # nixpkgs.overlays = [
  #   (
  #     final: prev: {
  #       mastodon = prev.mastodon.overrideAttrs (oldAttrs: {
  #         postPatch =
  #           (oldAttrs.postPatch or "")
  #           + ''
  #             patch -p1 < ${./chars.patch}
  #           '';
  #       });
  #     }
  #   )
  # ];

  microvm.vms = {
    ${serviceCfg.name} = {
      autostart = true;
      restartIfChanged = true;
      config = {
        system.stateVersion = "24.05";
        time.timeZone = "America/Winnipeg";
        users.users.root.openssh.authorizedKeys.keys = flake.config.people.users.${user0}.sshKeys;
        services = {
          ${serviceCfg.name} = {
            enable = true;
            localDomain = host;
            secretKeyBaseFile = "/etc/mastodon-secrets/pass";
            streamingProcesses = 7;
            trustedProxy = hostCfg.localhost.address0;
            automaticMigrations = true;
            database = {
              createLocally = true;
              name = serviceCfg.name;
              host = "/run/postgresql";
              user = serviceCfg.name;
              passwordFile = "/etc/mastodon-secrets/database";
            };
            extraConfig = {
              SINGLE_USER_MODE = "true";
              SMTP_AUTH_METHOD = "plain";
              SMTP_DELIVERY_METHOD = "smtp";
              SMTP_ENABLE_STARTTLS_AUTO = "true";
              SMTP_SSL = "false";
            };
            mediaAutoRemove = {
              enable = true;
              olderThanDays = 14;
            };
            redis = {
              createLocally = true;
              enableUnixSocket = true;
            };
            sidekiqThreads = 25;
            sidekiqProcesses = {
              all = {
                jobClasses = [
                ];
                threads = null;
              };
              default = {
                jobClasses = [
                  "default"
                ];
                threads = 5;
              };
              ingress = {
                jobClasses = [
                  "ingress"
                ];
                threads = 5;
              };
              push-pull = {
                jobClasses = [
                  "push"
                  "pull"
                ];
                threads = 5;
              };
              mailers = {
                jobClasses = [
                  "mailers"
                ];
                threads = 5;
              };
            };
            smtp = {
              authenticate = true;
              createLocally = false;
              fromAddress = "upRootNutrition <${smtpCfg.email.address1}>";
              host = smtpCfg.hostname;
              passwordFile = "/etc/mastodon-secrets/smtp";
              port = smtpCfg.ports.port1;
              user = smtpCfg.email.address1;
            };
          };
          caddy = {
            enable = true;
            virtualHosts = {
              ":80" = {
                extraConfig = ''
                  # Remove the outer http:// block wrapper
                  handle_path /system/* {
                    file_server * {
                      root /var/lib/mastodon/public-system
                    }
                  }

                  handle /api/v1/streaming/* {
                    reverse_proxy unix//run/mastodon-streaming/streaming.socket {
                      header_up X-Forwarded-Proto {http.request.header.X-Forwarded-Proto}
                      header_up X-Forwarded-Host {http.request.header.X-Forwarded-Host}
                    }
                  }

                  route * {
                    file_server * {
                      root ${pkgs.mastodon}/public
                      pass_thru
                    }
                    reverse_proxy * unix//run/mastodon-web/web.socket {
                      header_up X-Forwarded-Proto {http.request.header.X-Forwarded-Proto}
                      header_up X-Forwarded-Host {http.request.header.X-Forwarded-Host}
                    }
                  }

                  handle_errors {
                    root * ${pkgs.mastodon}/public
                    rewrite 500.html
                    file_server
                  }

                  encode gzip

                  header /* {
                    Strict-Transport-Security "max-age=31536000;"
                  }

                  header /emoji/* Cache-Control "public, max-age=31536000, immutable"
                  header /packs/* Cache-Control "public, max-age=31536000, immutable"
                  header /system/accounts/avatars/* Cache-Control "public, max-age=31536000, immutable"
                  header /system/media_attachments/files/* Cache-Control "public, max-age=31536000, immutable"
                '';
              };
            };
          };

          postgresql = {
            enable = true;
          };

          openssh = {
            enable = true;
            settings = {
              PasswordAuthentication = false;
              PermitRootLogin = "prohibit-password";
            };
          };
        };

        users.users.${serviceCfg.name}.extraGroups = [
          "postgres"
        ];
        users.users.caddy.extraGroups = [
          serviceCfg.name
        ];

        networking.firewall.allowedTCPPorts = [
          22 # SSH
          80 # Caddy
          25 # SMTP
          139 # SMTP
          587 # SMTP
          2525 # SMTP
          5432 # Postgres
        ];

        systemd = {
          services = {
            mastodon-init-dirs = {
              serviceConfig = {
                PrivateMounts = lib.mkForce false;
              };
            };
            mastodon-web = {
              serviceConfig = {
                PrivateMounts = lib.mkForce false;
              };
            };
            mastodon-streaming-1 = {
              serviceConfig = {
                PrivateMounts = lib.mkForce false;
              };
            };
            mastodon-streaming-2.serviceConfig.PrivateMounts = lib.mkForce false;
            mastodon-streaming-3.serviceConfig.PrivateMounts = lib.mkForce false;
            mastodon-streaming-4.serviceConfig.PrivateMounts = lib.mkForce false;
            mastodon-streaming-5.serviceConfig.PrivateMounts = lib.mkForce false;
            mastodon-streaming-6.serviceConfig.PrivateMounts = lib.mkForce false;
            mastodon-streaming-7.serviceConfig.PrivateMounts = lib.mkForce false;
            mastodon-sidekiq-all.serviceConfig.PrivateMounts = lib.mkForce false;
            mastodon-sidekiq-default.serviceConfig.PrivateMounts = lib.mkForce false;
            mastodon-sidekiq-ingress.serviceConfig.PrivateMounts = lib.mkForce false;
            mastodon-sidekiq-mailers.serviceConfig.PrivateMounts = lib.mkForce false;
            mastodon-sidekiq-push-pull.serviceConfig.PrivateMounts = lib.mkForce false;
            mastodon-copy-secrets = {
              description = "Copy secrets from virtiofs to local filesystem";
              before = [ "mastodon-init-dirs.service" ];
              requiredBy = [ "mastodon-init-dirs.service" ];

              serviceConfig = {
                Type = "oneshot";
                RemainAfterExit = true;
              };

              script = ''
                mkdir -p /etc/mastodon-secrets
                cp /run/secrets/pass /etc/mastodon-secrets/pass
                cp /run/secrets/database /etc/mastodon-secrets/database
                cp /run/secrets/redis /etc/mastodon-secrets/redis
                cp /run/secrets/smtp /etc/mastodon-secrets/smtp
                chmod 755 /etc/mastodon-secrets
                chmod 644 /etc/mastodon-secrets/*
              '';
            };
          };
          network = {
            enable = true;
            networks."20-lan" = {
              matchConfig.Name = "enp0s6";
              addresses = [ { Address = "${serviceCfg.interface.ip}/24"; } ];
              routes = [
                {
                  Destination = "${hostCfg.localhost.address1}/0";
                  Gateway = serviceCfg.interface.gate;
                }
              ];
              dns = [
                "1.1.1.1"
                "8.8.8.8"
              ];
            };
          };
          services = {
            mastodon-init-db = {
              serviceConfig = {
                EnvironmentFile = "/var/lib/mastodon/.secrets_env";
              };
            };
            systemd-tmpfiles-setup.after = [ "var-lib-mastodon.mount" ];
          };
          tmpfiles.rules = [
            "d /var/lib/mastodon 0755 mastodon mastodon -"
            "Z /var/lib/mastodon 0755 mastodon mastodon -"
            "Z /var/lib/postgresql 0755 postgres postgres -"
            "d /var/cache/mastodon/precompile 0755 mastodon mastodon -"
            "d /var/lib/mastodon/public-system 0755 mastodon mastodon -"
            "d /var/lib/mastodon/public-system/accounts 0755 mastodon mastodon -"
            "d /var/lib/mastodon/public-system/media_attachments 0755 mastodon mastodon -"
            "d /var/lib/mastodon/public-system/media_attachments/files 0755 mastodon mastodon -"
            "d /var/lib/mastodon/public-system/site_uploads 0755 mastodon mastodon -"
          ];
        };

        microvm = {
          vcpu = 4;
          mem = 8192;
          hypervisor = "qemu";
          interfaces = [
            {
              type = "tap";
              id = serviceCfg.interface.id;
              mac = serviceCfg.interface.mac;
            }
            {
              type = "user";
              id = serviceCfg.interface.idUser;
              mac = serviceCfg.interface.macUser;
            }
          ];
          forwardPorts = [
            {
              from = "host";
              host.port = serviceCfg.interface.ssh;
              guest.port = 22;
            }
          ];
          shares = [
            {
              mountPoint = "/nix/.ro-store";
              proto = "virtiofs";
              source = "/nix/store";
              tag = "read_only_nix_store";
            }
            {
              mountPoint = "/var/lib/${serviceCfg.name}";
              proto = "virtiofs";
              source = "${serviceCfg.mntPaths.path0}/data";
              tag = "${serviceCfg.name}_data";
            }
            {
              mountPoint = "/var/lib/postgresql";
              proto = "virtiofs";
              source = "${serviceCfg.mntPaths.path0}/database";
              tag = "${serviceCfg.name}_database";
            }
            {
              mountPoint = "/run/secrets";
              proto = "virtiofs";
              source = "/run/secrets/${serviceCfg.name}";
              tag = "host_secrets";
            }
          ];
        };
      };
    };
  };

  sops = {
    secrets = builtins.listToAttrs (
      map
        (secret: {
          name = "${serviceCfg.name}/${secret}";
          value = {
            owner = "root";
            group = "root";
            mode = "0644";
          };
        })
        [
          "smtp"
          "database"
          "redis"
          "pass"
        ]
    );
  };

  systemd.tmpfiles.rules = [
    "d ${serviceCfg.mntPaths.path0} 0751 microvm wheel - -"
    "d ${serviceCfg.mntPaths.path0}/data 0751 microvm wheel - -"
    "d ${serviceCfg.mntPaths.path0}/database 0751 microvm wheel - -"
  ];

  services.caddy.virtualHosts."${host}" = {
    extraConfig = ''
      reverse_proxy http://${serviceCfg.interface.ip}:80 {
        header_up X-Forwarded-Proto {scheme}
        header_up X-Real-IP {remote_host}
        header_up X-Forwarded-For {remote_host}
      }

      tls ${serviceCfg.ssl.cert} ${serviceCfg.ssl.key}

      encode zstd gzip
    '';
  };

  users.users.caddy.extraGroups = [ "acme" ];

  security.acme.certs."${host}" = {
    dnsProvider = dns0;
    environmentFile = config.sops.secrets.${dns0Path}.path;
    group = "caddy";
  };
}
