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

with lib;
let
  hostname = "nutboy3";
  host-fqdn = config.instance.host-fqdn;
  host-ipv4 = "199.87.154.175";
  domain-name = config.fudo.hosts.${hostname}.domain;
  domain = config.fudo.domains.${domain-name};
  site-name = config.fudo.hosts.${hostname}.site;
  site = config.fudo.sites.${site-name};

  local-packages = with pkgs; [ ldns.examples ];

  host-secrets = config.fudo.secrets.host-secrets.${hostname};

  postgresql-user = config.systemd.services.postgresql.serviceConfig.User;

  files = config.fudo.secrets.files;

  acme-copies = config.fudo.acme.host-domains.${hostname};

  grafana-database-passwd-file =
    pkgs.lib.passwd.stablerandom-passwd-file "grafana-database-password"
    "grafana-database-password-${config.instance.build-seed}";

in {

  imports = [
    ./nutboy3/cashew.nix
    # ./nutboy3/forum_selby_ca.nix
  ];

  config = {
    networking = {
      nameservers = [ "1.1.1.1" ];
      defaultGateway = {
        address = site.gateway-v4;
        interface = "extif0";
      };

      interfaces.extif0.ipv4.addresses = [{
        address = host-ipv4;
        prefixLength = 31;
      }];
    };

    systemd = {
      tmpfiles.rules = [
        "L /etc/adjtime - - - - /state/etc/adjtime"
        "d /state/services 0555 - - - -"
      ];
      services.grafana = {
        bindsTo = [ "postgresql.service" ];
        requires = [ "postgresql.service" ];
      };
    };

    environment = { systemPackages = local-packages; };

    security.acme.email = "admin@fudo.org";

    fudo = {
      hosts.${hostname}.external-interfaces = [ "extif0" ];

      secrets.host-secrets.${hostname} = let files = config.fudo.secrets.files;
      in {
        heimdal-master-key = {
          source-file = files.realm-master-keys."FUDO.ORG";
          target-file = "/run/heimdal/master-key";
          user = config.fudo.auth.kdc.user;
        };

        ldap-keytab = {
          source-file = files.service-keytabs.${hostname}.openldap;
          target-file = "/run/openldap/ldap.keytab";
          user = config.services.openldap.user;
        };

        postgresql-keytab = {
          source-file = files.service-keytabs.nutboy3.postgres;
          target-file = "/run/postgresql/postgres.keytab";
          user = postgresql-user;
        };

        grafana-database-password = {
          source-file = grafana-database-passwd-file;
          target-file = "/run/metrics/grafana/db.passwd";
          user = config.systemd.services.grafana.serviceConfig.User;
        };

        postgres-grafana-password = {
          source-file = grafana-database-passwd-file;
          target-file = "/run/postgres-users/grafana.passwd";
          user = config.services.postgresql.superUser;
        };
      };

      acme.host-domains.${hostname} = {
        ${host-fqdn}.local-copies = {
          openldap = {
            user = config.services.openldap.user;
            dependent-services = [ "openldap.service" ];
            part-of = [ config.fudo.auth.ldap-server.systemd-target ];
          };

          postgresql = {
            user = postgresql-user;
            dependent-services = [ "postgresql.service" ];
            part-of = [ config.fudo.postgresql.systemd-target ];
          };
        };
      };

      client.dns = {
        ipv4 = true;
        ipv6 = true;
        user = "fudo-client";
        external-interface = "extif0";
      };

      services = {
        jabber = {
          domain = "jabber.fudo.org";
          ldap.servers = [ "nutboy3.fudo.org" ];
          state-directory = "/state/ejabberd";
        };

        auth = {
          ldap.state-directory = "/state/auth/ldap";
          kerberos = {
            state-directory = "/state/auth/kerberos";
            master-key-file = host-secrets.heimdal-master-key.target-file;
          };
        };

        postgresql = {
          state-directory = "/state/services/postgresql";
          keytab =
            config.fudo.secrets.files.service-keytabs.${hostname}.postgres;
        };

        metrics = {
          prometheus.state-directory = "/state/services/prometheus";
          grafana = {
            state-directory = "/state/services/grafana";
            database = {
              user = "grafana";
              password-file =
                host-secrets.grafana-database-password.target-file;
            };
          };
        };

        logging.loki.state-directory = "/state/services/loki";

        selby-forum = {
          enable = true;
          state-directory = "/state/services/selby-forum";
          legacy-forum-data = files.blobs."selby-forum-2021-12-14.clean";
          external-interface = "extif0";
          mail.host = "mail.fudo.org";
        };
      };

      # dns.state-directory = "/state/nsd";

      # mail-server = {
      #   enableContainer = true;
      #   debug = true;

      #   domain = domain-name;
      #   mail-hostname = "${host-fqdn}";
      #   monitoring = false;
      #   mail-user = "mailuser";
      #   mail-user-id = 525;
      #   mail-group = "mailgroup";
      #   clamav.enable = true;
      #   dkim.signing = true;

      #   dovecot = {
      #     ssl-certificate = acme-certificate "imap.${domain-name}";
      #     ssl-private-key = acme-private-key "imap.${domain-name}";
      #   };

      #   postfix = {
      #     ssl-certificate = acme-certificate "smtp.${domain-name}";
      #     ssl-private-key = acme-private-key "smtp.${domain-name}";
      #   };

      #   # This should NOT include the primary domain
      #   local-domains = [ host-fqdn "smtp.${domain-name}" ];

      #   mail-directory = "/srv/mailserver/mail";
      #   state-directory = "/srv/mailserver/state";

      #   trusted-networks = [ "172.86.179.16/29" "127.0.0.0/16" ];

      #   alias-users = {
      #     root = [ "niten" ];
      #     postmaster = [ "niten" ];
      #     hostmaster = [ "niten" ];
      #     webmaster = [ "niten" ];
      #     system = [ "niten" ];
      #     admin = [ "niten" ];
      #     dmarc-report = [ "niten" ];
      #   };
      # };

      postgresql = {
        databases.grafana.users = config.instance.local-admins;

        users.grafana = {
          password-file = host-secrets.postgres-grafana-password.target-file;
          databases.grafana = {
            access = "CONNECT";
            entity-access = {
              "ALL TABLES IN SCHEMA public" = "ALL PRIVILEGES";
              # "SELECT,INSERT,UPDATE,DELETE";
              "ALL SEQUENCES IN SCHEMA public" = "ALL PRIVILEGES";
              # "SELECT, UPDATE";
            };
          };
        };
      };

      # git = {
      #   enable = true;
      #   hostname = "git.informis.land";
      #   site-name = "informis git";
      #   user = "gituser";
      #   repository-dir = /srv/git/repo;
      #   state-dir = /srv/git/state;
      #   database = {
      #     user = "gituser";
      #     password-file =
      #       host-secrets.gitea-database-password.target-file;
      #     hostname = "127.0.0.1";
      #     name = "git";
      #   };
      #   ssh = {
      #     listen-ip = host-ipv4;
      #     listen-port = 2222;
      #   };
      # };
    };
  };
}