{
  config,
  pkgs,
  lib,
  ...
}:
let
  cfg = config.services.sqliteWeb;
in
{
  meta.maintainers = with lib.maintainers; [ ];

  options.services.sqliteWeb = {
    enable = lib.mkEnableOption "sqlite-web, a Web-based SQLite database browser written in Python";

    package = lib.mkOption {
      description = "sqlite-web package to use";
      type = lib.types.package;
      example = lib.literalExpression "pkgs.sqlite-web";
      default = pkgs.sqlite-web;
      defaultText = "pkgs.sqlite-web";
    };

    databases = lib.mkOption {
      description = "Configuration for multiple instances of sqlite-web";

      type = lib.types.attrsOf (
        lib.types.submodule {
          options = {
            port = lib.mkOption {
              description = "Port to serve the interface on";
              type = lib.types.port;
              example = 8080;
            };

            file = lib.mkOption {
              description = "Path to the sqlite database";
              type = lib.types.path;
              example = "/nix/var/nix/db/db.sqlite";
            };

            user = lib.mkOption {
              description = ''
                The user that owns the database file, and which
                the service should run under
              '';
              type = lib.types.str;
              example = "eve";
            };

            readOnly = lib.mkOption {
              description = "Do not allow editing the database via the interface";
              type = lib.types.bool;
              default = false;
              example = true;
            };

            passwordFile = lib.mkOption {
              description = ''
                File containing the password to use for authentication.
                Set to `null` to disable authentication
              '';
              type = lib.types.nullOr lib.types.path;
              default = null;
              example = "/run/keys/sqlite-web-password";
            };

            urlPrefix = lib.mkOption {
              description = "Prefix for all url paths";
              type = lib.types.nullOr lib.types.str;
              default = null;
              example = "/db/";
            };

            extraFlags = lib.mkOption {
              description = "Extra flags to pass to the sqlite-web command";
              type = with lib.types; either str (listOf str);
              default = [ ];
              example = [
                "--no-truncate"
                "--foreign-keys"
              ];
            };
          };
        }
      );

      default = { };
      example = {
        "nix-store-db" = {
          port = 8080;
          file = "/nix/var/nix/db/db.sqlite";
          readOnly = true;
        };
      };
    };
  };

  config = lib.mkIf cfg.enable {
    systemd.services = lib.attrsets.mapAttrs' (name: instance: {
      name = "sqlite-web-${name}";
      value = {
        wantedBy = [ "multi-user.target" ];
        after = [ "network.target" ];
        description = "Web-based SQLite database browser written in Python";

        script = ''
          ${lib.optionalString (instance.passwordFile != null) ''
            export SQLITE_WEB_PASSWORD=$(cat "''${CREDENTIALS_DIRECTORY}/password")
          ''}

          ${lib.getExe cfg.package} ${
            lib.escapeShellArgs (
              [ "--port=${toString instance.port}" ]
              ++ lib.lists.optional (instance.urlPrefix != null) "--url-prefix=${instance.urlPrefix}"
              ++ lib.lists.optional (instance.passwordFile != null) "--password"
              ++ instance.extraFlags
              ++ [ instance.file ]
            )
          }
        '';

        serviceConfig = {
          LoadCredential = lib.optional (instance.passwordFile != null) "password:${instance.passwordFile}";
          ReadOnlyPaths = lib.lists.optional instance.readOnly instance.file;
          ReadWritePaths = lib.lists.optional (!instance.readOnly) instance.file;
          User = instance.user;
          Restart = "on-failure";

          # Hardening
          AmbientCapabilities = "";
          CapabilityBoundingSet = "";
          DeviceAllow = "";
          LockPersonality = true;
          NoNewPrivileges = true;
          PrivateDevices = true;
          PrivateMounts = true;
          PrivateTmp = true;
          PrivateUsers = true;
          ProtectClock = true;
          ProtectControlGroups = true;
          ProtectKernelLogs = true;
          ProtectKernelModules = true;
          ProtectKernelTunables = true;
          ProtectSystem = "strict";
        };
      };
    }) cfg.databases;
  };
}