{ self, config, lib, pkgs, ... }:

with lib;

let
  cfg = config.services.microbin;
  configFile = "/etc/microbin/config";
  dataFolder = "/var/lib/microbin";
in
{
  options = {

    services.microbin = {
      enable = mkEnableOption "A super tiny pasta";

      user = mkOption {
        type = types.str;
        default = "microbin";
        description = "User account under which microbin runs.";
      };

      group = mkOption {
        type = types.str;
        default = "microbin";
        description = "Group account under which microbin runs.";
      };

      hostname = mkOption {
        type = types.str;
        description = "Hostname of your microbin service";
      };

      port = mkOption {
        type = types.port;
        default = 8080;
        description = "Port on which to run the serice";
      };

    };
  };

  config = mkIf cfg.enable {
    systemd.services.microbin = {
      description = "Microbin A Super Tiny Pasta";
      after = [ "remote-fs.target" "network.target" ];
      wantedBy = [ "multi-user.target" ];
      serviceConfig = {
        ExecStart = "${pkgs.unstable.microbin}/bin/microbin --public-path https://${cfg.hostname}/ --qr --enable-burn-after --private";
        Environment = [
          "MICROBIN_EDITABLE=true"
          "MICROBIN_HIDE_FOOTER=true"
          "MICROBIN_HIGHLIGHTSYNTAX=true"
          "MICROBIN_PORT=${builtins.toString cfg.port}"
          "MICROBIN_TITLE=SealightBin"
        ];
        WorkingDirectory = dataFolder;
        TimeoutStopSec = " 20 ";
        KillMode = " process ";
        RestartSec = " 10 ";
        User = cfg.user;
        Group = cfg.group;
        DevicePolicy = " closed ";
        NoNewPrivileges = " yes ";
        PrivateTmp = " yes ";
        PrivateUsers = " yes ";
        ProtectControlGroups = " yes ";
        ProtectKernelModules = " yes ";
        ProtectKernelTunables = " yes ";
        RestrictAddressFamilies = "
          AF_UNIX
          AF_INET
          AF_INET6 ";
        RestrictNamespaces = " yes ";
        RestrictRealtime = " yes ";
        SystemCallFilter = "~@clock @debug @module @mount @obsolete @privileged @reboot @setuid @swap";
        ReadWritePaths = dataFolder;
        StateDirectory = baseNameOf dataFolder;
      };
    };

    users.users = optionalAttrs (cfg.user == "microbin") ({
      microbin = {
        description = "microbin service user";
        name = cfg.user;
        group = cfg.group;
        isSystemUser = true;
      };
    });

    users.groups = optionalAttrs (cfg.group == "microbin") ({
      microbin = { };
    });
  };
}

