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

let
  inherit (depot.nix.pkgs) baserow;

  environment = {
    DJANGO_SETTINGS_MODULE = "baserow.config.settings.base";
    PUBLIC_WEB_FRONTEND_URL = "https://baserow.lukegb.com";
    PUBLIC_BACKEND_URL = "https://api.baserow.lukegb.com";
    PRIVATE_BACKEND_URL = "http://localhost:28100";
    MEDIA_URL = "https://baserow-media.zxcvbnm.ninja/";
    MJML_SERVER_HOST = "localhost";
    MEDIA_ROOT = "/var/lib/baserow/media";

    SECRET_KEY = "zKBu7MIzBki5S3rResh5Vj0kG7Fl0b27OUYCDJvRxe7fWJUcAHL1cR70hZuqECnszFVwSgxv1ZHBaHv6";

    DATABASE_HOST = "";
    DATABASE_PASSWORD = "";
    REDIS_HOST = "localhost";
    EMAIL_SMTP = "yesplease";
    FROM_EMAIL = "no-reply@baserow.lukegb.com";
  };
  baserow-util = pkgs.stdenv.mkDerivation {
    name = "baserow-util";
    dontUnpack = true;
    dontBuild = true;
    nativeBuildInputs = with pkgs; [ makeWrapper ];
    baserow = baserow.backend;
    installPhase = ''
      install -d -m 0755 $out/bin
      makeWrapper $baserow/bin/baserow $out/bin/baserow \
        ${lib.concatStringsSep "\n" (lib.mapAttrsToList (name: val: "--set-default '${name}' '${val}' \\") environment)}
    '';
  };
in
{
  environment.systemPackages = [ baserow-util ];

  users.groups.baserow = {};
  users.users.baserow = {
    group = "baserow";
    isSystemUser = true;
  };

  systemd.tmpfiles.rules = [
    "d /var/lib/baserow 0755 baserow baserow -"
    "d /var/lib/baserow/media 0750 baserow baserow -"
  ];

  services.postgresql = {
    enable = true;
    ensureUsers = [{
      name = "baserow";
      ensurePermissions = {
        "DATABASE baserow" = "ALL PRIVILEGES";
      };
    }];
    ensureDatabases = [ "baserow" ];
  };
  services.redis.servers."".enable = true;

  systemd.services.baserow-mjml-tcpserver = {
    wantedBy = [ "multi-user.target" ];
    after = [ "network.target" ];

    serviceConfig = {
      ExecStart = "${baserow.mjml-tcpserver}/bin/mjml-tcpserver --port=28101 --host=127.0.0.1 --mjml.minify=true --mjml.validationLevel=strict";
      User = "baserow";
      Group = "baserow";
      PrivateTmp = true;
      PrivateDevices = true;
      Restart = "on-failure";
    };
  };
  systemd.services.baserow-frontend = {
    wantedBy = [ "multi-user.target" ];
    after = [ "network.target" ];
    inherit environment;

    serviceConfig = {
      ExecStart = "${baserow.web-frontend}/bin/baserow-web-frontend --hostname 127.0.0.1 --port 28102";
      User = "baserow";
      Group = "baserow";
      PrivateTmp = true;
      PrivateDevices = true;
      Restart = "on-failure";
    };
  };
  systemd.services.baserow-backend = {
    wantedBy = [ "multi-user.target" ];
    after = [ "network.target" ];
    inherit environment;

    serviceConfig = {
      ExecStart = "${baserow.backend}/bin/baserow-gunicorn -w 5 -b 127.0.0.1:28100 --log-level=debug";
      User = "baserow";
      Group = "baserow";
      PrivateTmp = true;
      PrivateDevices = true;
      Restart = "on-failure";
    };
  };
  systemd.services.baserow-worker-celery = {
    wantedBy = [ "multi-user.target" ];
    after = [ "network.target" ];
    inherit environment;

    serviceConfig = {
      ExecStart = "${baserow.backend}/bin/baserow-celery worker -l INFO -Q celery";
      User = "baserow";
      Group = "baserow";
      PrivateTmp = true;
      PrivateDevices = true;
      Restart = "on-failure";
    };
  };
  systemd.services.baserow-worker-export = {
    wantedBy = [ "multi-user.target" ];
    after = [ "network.target" ];
    inherit environment;

    serviceConfig = {
      ExecStart = "${baserow.backend}/bin/baserow-celery worker -l INFO -Q export";
      User = "baserow";
      Group = "baserow";
      PrivateTmp = true;
      PrivateDevices = true;
      Restart = "on-failure";
    };
  };
  systemd.services.baserow-worker-beat = {
    wantedBy = [ "multi-user.target" ];
    after = [ "network.target" ];
    inherit environment;

    serviceConfig = {
      ExecStart = "${baserow.backend}/bin/baserow-celery beat -l INFO -S redbeat.RedBeatScheduler";
      User = "baserow";
      Group = "baserow";
      PrivateTmp = true;
      PrivateDevices = true;
      Restart = "on-failure";
    };
  };

  users.users.nginx.extraGroups = [ "baserow" ];
  services.nginx.recommendedProxySettings = true;
  services.nginx.recommendedTlsSettings = true;
  services.nginx.virtualHosts = {
    "baserow.lukegb.com" = {
      enableACME = true;
      forceSSL = true;
      extraConfig = ''
        proxy_read_timeout 1800s;
        client_max_body_size 0;
        chunked_transfer_encoding on;
      '';
      locations."/" = {
        proxyPass = "http://127.0.0.1:28102";
      };
    };
    "api.baserow.lukegb.com" = {
      enableACME = true;
      forceSSL = true;
      extraConfig = ''
        proxy_read_timeout 1800s;
        client_max_body_size 0;
        chunked_transfer_encoding on;
      '';
      locations."/" = {
        proxyPass = "http://127.0.0.1:28100";
        proxyWebsockets = true;
      };
    };
    "baserow-media.zxcvbnm.ninja" = {
      enableACME = true;
      forceSSL = true;

      root = "/var/lib/baserow/media";
      locations."/user_files" = {
        root = "/var/lib/baserow/media";
        extraConfig = ''
          add_header Content-disposition "attachment; filename=$1";
        '';
      };
      locations."/export_files" = {
        root = "/var/lib/baserow/media";
        extraConfig = ''
          add_header Content-disposition "attachment; filename=$1";
        '';
      };
    };
  };

  services.postfix = {
    enable = true;
    domain = "baserow.lukegb.com";
    hostname = "baserow.lukegb.com";
    extraConfig = ''
      milter_protocol = 2
      milter_default_action = accept
      smtpd_milters = ${config.services.opendkim.socket}
      non_smtpd_milters = ${config.services.opendkim.socket}
    '';
  };
  users.users.postfix.extraGroups = [ "opendkim" ];
  services.opendkim = {
    enable = true;
    domains = "csl:baserow.lukegb.com";
    selector = "totoro";
  };
  systemd.services.opendkim.serviceConfig.UMask = lib.mkForce "0007";
}