{ config, pkgs, ... }:

let
  host = "cloud.dgnum.eu";
  nextcloud-occ = "${config.services.nextcloud.occ}/bin/nextcloud-occ";
in {
  services.nextcloud = {
    enable = true;
    hostName = host;

    package = pkgs.nextcloud28;

    https = true;

    config = {
      overwriteProtocol = "https";

      dbtype = "pgsql";

      adminpassFile = config.age.secrets."nextcloud-adminpass_file".path;
      adminuser = "thubrecht";

      defaultPhoneRegion = "FR";

      trustedProxies = [ "::1" ];

      objectstore.s3 = {
        enable = true;

        hostname = "s3.dgnum.eu";
        region = "garage";
        usePathStyle = true;
        port = 443;

        bucket = "nextcloud-dgnum";
        key = "GKda5367c73ca607c349d83c35";
        verify_bucket_exists = false;
        secretFile = config.age.secrets."nextcloud-s3_secret_file".path;
      };
    };

    maxUploadSize = "4G";

    poolSettings = {
      pm = "dynamic";
      "pm.max_children" = 64;
      "pm.max_requests" = "500";
      "pm.max_spare_servers" = "8";
      "pm.min_spare_servers" = "4";
      "pm.start_servers" = "6";
    };

    phpOptions = {
      short_open_tag = "Off";
      expose_php = "Off";
      error_reporting = "E_ALL & ~E_DEPRECATED & ~E_STRICT";
      display_errors = "stderr";
      "opcache.enable_cli" = "1";
      "opcache.interned_strings_buffer" = "32";
      "opcache.max_accelerated_files" = "10000";
      "opcache.memory_consumption" = "128";
      "opcache.revalidate_freq" = "1";
      "opcache.fast_shutdown" = "1";
      "openssl.cafile" = "/etc/ssl/certs/ca-certificates.crt";
      catch_workers_output = "yes";
    };

    database.createLocally = true;
    configureRedis = true;

    autoUpdateApps.enable = true;

    extraOptions = {
      overwritehost = host;
      "overwrite.cli.url" = "https://${host}";
      updatechecker = false;

      allow_local_remote_servers = true;

      "memories.exiftool" = "${pkgs.lib.getExe pkgs.exiftool}";
      "memories.vod.ffmpeg" = "${pkgs.lib.getExe pkgs.ffmpeg-headless}";
      "memories.vod.ffprobe" = "${pkgs.ffmpeg-headless}/bin/ffprobe";
    };
  };

  virtualisation = {
    podman = {
      enable = true;

      defaultNetwork.settings = {
        dns_enable = true;
        ipv6_enabled = true;
      };
    };
  };

  virtualisation.oci-containers = {
    # # Since 22.05, the default driver is podman but it doesn't work
    # # with podman. It would however be nice to switch to podman.
    # backend = "docker";
    containers.collabora = {
      image = "collabora/code";
      imageFile = pkgs.dockerTools.pullImage {
        imageName = "collabora/code";
        imageDigest =
          "sha256:a8cce07c949aa59cea0a7f1f220266a1a6d886c717c3b5005782baf6f384d645";
        sha256 = "sha256-lN6skv62x+x7G7SNOUyZ8W6S/uScrkqE1nbBwwSEWXQ=";
      };
      ports = [ "9980:9980" ];
      environment = {
        domain = "cloud.dgnum.eu";
        extra_params = "--o:ssl.enable=false --o:ssl.termination=true --o:remote_font_config.url=https://cloud.dgnum.eu/apps/richdocuments/settings/fonts.json";
      };
      extraOptions = [ "--cap-add" "MKNOD" "--cap-add" "SYS_ADMIN" ];
    };
  };

  services.nginx.virtualHosts = {
    ${host} = {
      enableACME = true;
      forceSSL = true;

      extraConfig = ''
        proxy_max_temp_file_size 4096m;
      '';
    };

    "code.dgnum.eu" = {
      forceSSL = true;
      enableACME = true;

      extraConfig = ''
        # static files
        location ^~ /browser {
          proxy_pass http://127.0.0.1:9980;
          proxy_set_header Host $host;
        }

        # WOPI discovery URL
        location ^~ /hosting/discovery {
          proxy_pass http://127.0.0.1:9980;
          proxy_set_header Host $host;
        }

        # Capabilities
        location ^~ /hosting/capabilities {
          proxy_pass http://127.0.0.1:9980;
          proxy_set_header Host $host;
        }

        # main websocket
        location ~ ^/cool/(.*)/ws$ {
          proxy_pass http://127.0.0.1:9980;
          proxy_set_header Upgrade $http_upgrade;
          proxy_set_header Connection "Upgrade";
          proxy_set_header Host $host;
          proxy_read_timeout 36000s;
        }

        # download, presentation and image upload
        location ~ ^/(c|l)ool {
          proxy_pass http://127.0.0.1:9980;
          proxy_set_header Host $host;
        }

        # Admin Console websocket
        location ^~ /cool/adminws {
          proxy_pass http://127.0.0.1:9980;
          proxy_set_header Upgrade $http_upgrade;
          proxy_set_header Connection "Upgrade";
          proxy_set_header Host $host;
          proxy_read_timeout 36000s;
        }
      '';
    };
  };

  systemd.services = {
    nextcloud-preview = {
      description = "Generate preview for nextcloud media.";
      script = "${nextcloud-occ} preview:pre-generate -vvv";
      startAt = "*-*-* 01:00:00 UTC";
      serviceConfig = { Restart = "on-failure"; };
    };

    nextcloud-cron.path = [ pkgs.perl ];
  };

  environment.systemPackages = [ pkgs.ffmpeg_6-headless ];

  networking.hosts = { "129.199.146.148" = [ "s3.dgnum.eu" ]; };

  age-secrets.matches."^nextcloud-.*$" = { owner = "nextcloud"; };

  system.activationScripts = {
    restart-nextcloud.text = ''
      if [ "$(${pkgs.systemd}/bin/systemctl is-active phpfpm-nextcloud)" == "active" ]; then
        ${pkgs.systemd}/bin/systemctl restart phpfpm-nextcloud
      fi
    '';
  };
}