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

let
  mattermost = pkgs.mattermost;
in {
  containers.mattermost = {
    autoStart = true;
    privateNetwork = true;
    hostAddress = "192.168.100.1";
    localAddress = "192.168.100.3";

    bindMounts = {
      "/persist" = {
        hostPath = "/persist/containers/mattermost";
        isReadOnly = false;
      };
    };

    path = (evalConfig {hosts = {}; groups = {};} ({ config, lib, pkgs, profiles, modules, sources, ... }: {
      boot.isContainer = true;
      networking.useDHCP = false;
      users.users.root.hashedPassword = "";

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

      nixpkgs.overlays = [ (self: super: { inherit mattermost; }) ];

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

      # couldn't figure out how to actually overwrite modules, so now
      # there's two mattermost modules ...
      services.mattermost-patched = {
        enable = true;
        siteUrl = "https://mattermost.infra4future.de";
        siteName = "Mattermost for Future";
        listenAddress = "0.0.0.0:3000";
        mutableConfig = false;

        secretConfig = "/persist/mattermost/secrets.json";
        statePath = "/persist/mattermost";

        extraConfig = {
          ServiceSettings = {
            TrustedProxyIPHeader = [ "X-Forwarded-For" "X-Real-Ip" ];
            ReadTimeout = 300;
            WriteTimeout = 600;
            IdleTimeout = 60;
            MaximumLoginAttempts = 10;
            AllowCorsFrom = "*.infra4future.de/*";
            WebserverMode = "gzip";
            EnableCustomEmoji = true;
            EnableEmojiPicker = true;
            EnableGifPicker = false;
            RestrictCustomEmojiCreation = "all";
            RestrictPostDelete = "all";
            AllowEditPost = "always";
            PostEditTimeout = -1;
            EnableTutorial = false;
            ExperimentalChannelSidebarOrganization = "default_on";
            ExperimentalChannelOrganization = true;
            ExperimentalDataPrefetch = true;
            EnableEmailInvitations = true;
            DisableLegacyMFA = true;
            EnableSVGs = true;
            EnableLaTeX = true;
            ThreadAutoFollow = true;
            EnableSecurityFixAlert = false;
            CollapsedThreads = "default_on";
          };
          TeamSettings = {
            EnableTeamCreation = true;
            EnableUserCreation = true;
            MaxUsersPerTeam = 250;
            EnableOpenServer = false;
            EnableUserDeactivation = true;
            ExperimentalViewArchivedChannels = true;
            ExperimentalEnableAutomaticReplies = true;
          };
          LogSettings = {
            EnableConsole = true;
            ConsoleLevel = "ERROR";
            EnableDiagnostics = false;
            EnableWebhookDebugging = false;
          };
          NotificationLogSettings = {
            EnableConsole = true;
            ConsoleLevel = "INFO";
          };
          PasswordSettings = {
            MinimumLength = 10;
            # turn of all the bullshit requirements
            Lowercase = false;
            Number = false;
            Uppercase = false;
            Symbol = false;
          };
          FileSettings = {
            EnableFileAttachments = true;
            MaxFileSize = 52428800;
            DriverName = "local";
            Directory = "/persist/mattermost/upload-storage";
            EnablePublicLink = true;
            PublicLinkSalt = "3k7p3yxdhz6798b3b9openfr9rn3ymwu";
          };
          EmailSettings = {
            EnableSignUpWithEmail = false;
            EnableSignInWithEmail = false;
            EnableSignInWithUsername = false;
            SendEmailNotifications = true;
            FeedbackName = "mattermost";
            FeedbackEmail = "mattermost@infra4future.de";
            ReplyToAddress = "mattermost@infra4future.de";
            FeedbackOrganization = "∆infra4future.de";
            EnableSMTPAuth = true;
            SMTPUsername = "noreply@infra4future.de";
            SMTPServer = "mail.hacc.space";
          };
          RateLimitSettings.Enable = false;
          PrivacySettings = {
            ShowEmailAddress = false;
            ShowFullName = true;
          };
          SupportSettings = {
            TermsOfServiceLink = "https://infra4future.de/nutzungsbedingungen.html";
            PrivacyPolicyLink = "https://infra4future.de/nutzungsbedingungen.html";
            AboutLink = "https://infra4future.de";
            SupportEmail = "info@infra4future.de";
            CustomTermsOfServiceEnabled = false;
            EnableAskCommunityLink = true;
          };
          AnnouncementSettings.EnableBanner = false;
          GitLabSettings = {
            Enable = true;
            Id = "mattermost";
            Scope = "";
            AuthEndpoint = "https://auth.infra4future.de/auth/realms/forfuture/protocol/openid-connect/auth";
            TokenEndpoint = "https://auth.infra4future.de/auth/realms/forfuture/protocol/openid-connect/token";
            UserApiEndpoint = "https://auth.infra4future.de/auth/realms/forfuture/protocol/openid-connect/userinfo";
          };
          # for some reason, these don't appear to be working; the startup
          # process complaines and sets these back to en
          LocalizationSettings = {
            DefaultServerLocale = "de";
            DefaultClientLocale = "de";
            AvailableLocales = "de,en";
          };
          MessageExportSettings.EnableExport = false;
          # plugins appear to have trouble with the read-only filesystem; it may
          # be necessary to manually change their paths etc.
          PluginSettings = {
            Enable = true;
            EnableUploads = true;
            Plugins = {
              bigbluebutton = {
                adminonly = false;
                base_url = "https://bbb.infra4future.de/bigbluebutton/api";
                salt = "zKCsNeaEniC115ynHOsZopgA4iTiJjzgeiPNoCEc";
              };
              "com.github.matterpoll.matterpoll" = {
                experimentalui = true;
                trigger = "poll";
              };
            };
            PluginStates = {
              bigbluebutton.Enable = true;
              "com.github.matterpoll.matterpoll".Enable = true;
            };
          };
          ComplianceSettings.Enable = false;
          ClusterSettings.Enable = false;
          MetricsSettings.Enable = false;
          GuestAccountsSettings.Enable = false;
          FeatureFlags.CollapsedThreads = true;
        };

        # turn of the weirder parts of this module (which insist on passwords
        # in nix files, instead of just using socket-based authentication)
        #
        # It will still attempt to use its default password, but postgres will
        # just let it in regardless of that.
        localDatabaseCreate = false;
      };

      services.mysql = {
        enable = true;
        ensureDatabases = [ "mattermost" ];
        ensureUsers = [ {
          name = "mattermost";
          ensurePermissions = { "mattermost.*" = "ALL PRIVILEGES"; };
        } ];
        package = pkgs.mysql80;
        dataDir = "/persist/mysql";
      };

      services.postgresql = {
        enable = lib.mkForce true; # mattermost sets this to false. wtf.
        package = pkgs.postgresql_11;
        ensureDatabases = [ "mattermost" ];
        ensureUsers = [ {
          name = "mattermost";
          ensurePermissions = { "DATABASE mattermost" = "ALL PRIVILEGES"; };
        } ];

        authentication = lib.mkForce ''
          # Generated file; do not edit!
          local all all              trust
          host  mattermost mattermost ::1/128      trust
        '';
      };

      networking.firewall.allowedTCPPorts = [ 3000 ];

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

  services.nginx.virtualHosts."mattermost.infra4future.de" = {
    locations."/" = {
      proxyPass = "http://${config.containers.mattermost.localAddress}:3000";
      proxyWebsockets = true;
      extraConfig = ''
        # Mattermost CSR Patch
        proxy_hide_header Content-Security-Policy;
        proxy_hide_header X-Frame-Options;
        proxy_redirect off;
      '';
    };
    forceSSL = true;
    enableACME = true;
  };
}