{ config, lib, pkgs, profiles, modules, evalConfig, ... }:

{
  containers.nextcloud = {
    autoStart = true;
    privateNetwork = true;
    hostAddress = "192.168.100.1";
    localAddress = "192.168.100.2";
    bindMounts = {
      "/persist" = {
        hostPath = "/persist/containers/nextcloud";
        isReadOnly = false;
      };
    };
    path = (evalConfig {hosts = {}; groups = {};} ({ config, lib, pkgs, profiles, modules, sources, ... }: {
      boot.isContainer = true;
      networking.useDHCP = false;
      users.users.root.hashedPassword = "";

      imports = [
        ((import sources.nix-hexchen) {}).profiles.nopersist
        ../../modules/nextcloud.nix
      ];

      nixpkgs.config.allowUnfree = true;
      networking.firewall.enable = false;
      networking.defaultGateway = {
        address = "192.168.100.1";
        interface = "eth0";
      };

      environment.systemPackages = [ pkgs.htop ];

      services.nextcloud-patched = {
        enable = true;

        # must be set manually; may not be incremented by more than one at
        # a time, otherwise nextcloud WILL break
        package = pkgs.nextcloud21;

        home = "/persist/nextcloud";
        https = true;

        hostName = "cloud.infra4future.de";
        config = {
          dbtype = "pgsql";
          dbuser = "nextcloud";
          dbhost = "/run/postgresql"; # nextcloud will add /.s.PGSQL.5432 by itself
          dbname = "nextcloud";
          adminpassFile = "/persist/nextcloud/config/admin_pw";
          adminuser = "root";
          defaultapp = "apporder";
        };

        caching.redis = true;

        # multiple pools may be doable using services.phpfpm.pools,
        # but i have not tried this yet. The nextcloud module defines a
        # pool "nextcloud"
        poolSettings = {
          pm = "dynamic";
          "pm.max_children" = "32";
          "pm.max_requests" = "500";
          "pm.max_spare_servers" = "4";
          "pm.min_spare_servers" = "2";
          "pm.start_servers" = "2";
        };

        extraOptions = {
          instanceid = "ocxlphb7fbju";
          redis = {
            host = "/run/redis/redis.sock";
            port = 0;
            dbindex = 0;
            password = "secret";
            timeout = 1.5;
          };
          datadirectory = "/persist/data/ncdata";
          mail_smtpmode = "smtp";
          mail_smtpsecure = "ssl";
          mail_sendmailmode = "smtp";
          mail_from_address = "noreply";
          mail_domain = "infra4future.de";
          mail_smtpauthtype = "PLAIN";
          mail_smtpauth = 1;
          mail_smtphost = "mail.hacc.space";
          mail_smtpport = 465;
          mail_smtpname = "noreply@infra4future.de";
          loglevel = 0;
          "overwrite.cli.url" = "https://cloud.infra4future.de";
        };

        # passwordsalt, secret, and mail_smtppassword go in here
        secretFile = "/persist/secrets.json";

      };

      services.redis = {
        enable = true;
        unixSocket = "/var/run/redis/redis.sock";
      };

      services.postgresql = {
        enable = true;
        package = pkgs.postgresql_11;
        ensureDatabases = [ "nextcloud" ];
        ensureUsers = [
          { # by default, postgres has unix sockets enabled, and allows a
            # system user `nextcloud` to log in without other authentication
            name = "nextcloud";
            ensurePermissions."DATABASE nextcloud" = "ALL PRIVILEGES";
          }
        ];
      };

      # ensure that postgres is running *before* running the setup
      systemd.services."nextcloud-setup" = {
        requires = ["postgresql.service"];
        after = ["postgresql.service"];
      };

      services.coredns = {
        enable = true;
        config = ''
          .:53 {
            forward . 1.1.1.1
          }
        '';
      };
    })).config.system.build.toplevel;
  };

  services.nginx.virtualHosts."cloud.infra4future.de" = {
    locations."/".proxyPass = "http://${config.containers.nextcloud.localAddress}:80";
    enableACME = true;
    forceSSL = true;
    extraConfig = ''
      proxy_buffering off;
      client_max_body_size 0;
      add_header Cache-Control "no-store, no-cache, must-revalidate";
    '';
  };

}
