# Guide: https://nixos-mailserver.readthedocs.io/en/latest/setup-guide.html
{
	config,
	const,
	container,
	lib,
	pkgs,
	util,
	...
}: let
	cfg    = config.container.module.mail;
	domain = config.container.domain;
in {
	options.container.module.mail = {
		enable = lib.mkEnableOption "the email server.";
		address = lib.mkOption {
			default = "10.1.0.5";
			type    = lib.types.str;
		};
		port = lib.mkOption {
			default = 80;
			type    = lib.types.int;
		};
		domain = lib.mkOption {
			default = "mail.${config.container.domain}";
			type    = lib.types.str;
		};
		storage = lib.mkOption {
			default = "${config.container.storage}/mail";
			type    = lib.types.str;
		};
	};

	config = lib.mkIf cfg.enable {
		systemd.tmpfiles.rules = container.mkContainerDir cfg [
			"data"
		];

		containers.mail = container.mkContainer cfg {
			bindMounts = {
				"/var/lib/dovecot/indices" = {
					hostPath   = "${cfg.storage}/data/indices";
					isReadOnly = false;
				};
				"/var/vmail" = {
					hostPath   = "${cfg.storage}/data/vmail";
					isReadOnly = false;
				};
				"/var/sieve" = {
					hostPath   = "${cfg.storage}/data/sieve";
					isReadOnly = false;
				};
				"/var/dkim" = {
					hostPath   = "${cfg.storage}/data/dkim";
					isReadOnly = false;
				};
				"/acme" = {
					hostPath   = "${config.container.module.proxy.storage}/letsencrypt";
					isReadOnly = true;
				};
			};

			config = { config, ... }: container.mkContainerConfig cfg {
				imports = [
					(builtins.fetchTarball {
						sha256 = "sha256:0clvw4622mqzk1aqw1qn6shl9pai097q62mq1ibzscnjayhp278b";
						url    = "https://gitlab.com/simple-nixos-mailserver/nixos-mailserver/-/archive/nixos-${const.stateVersion}/nixos-mailserver-nixos-${const.stateVersion}.tar.gz";
					})
				];

				mailserver = {
					enable = true;
					domains     = [ domain ];
					fqdn        = cfg.domain;
					sendingFqdn = domain;

					# Use `mkpasswd -sm bcrypt`.
					loginAccounts = let
						defaultQuota = "1G";
					in {
						"admin@${domain}" = {
							hashedPassword = "$2b$05$1O.dxXxaVshcBNybcqDRYuTlnYt3jDBwfPZWoDtP4BjOLoL0StYsi";
							name  = "admin";
							quota = defaultQuota;
						};
						"account@${domain}" = {
							hashedPassword = "$2b$05$sCyZHdk98KqQ1qsTIvbrUeRJlNBOwBqDgpdc1QxiSnONlEkZ8xGNO";
							name  = "account";
							quota = defaultQuota;
						};
						"hi@${domain}" = {
							hashedPassword = "$2b$05$6fT5hIhzIasNfp9IQr/ds.5RuxH95VKU3QJWlX3hmrAzDF3mExanq";
							name  = "hi";
							quota = defaultQuota;
							aliases = [
								"voronind@${domain}"
							];
						};
						"job@${domain}" = {
							hashedPassword = "$2b$05$.sUmv2.9EWPfLwJn/oZw2e1UbR7HrpNQ2THc5jjX3ysy7CY8ZWHUC";
							name  = "job";
							quota = defaultQuota;
						};
						"trash@${domain}" = {
							hashedPassword = "$2b$05$kn5ygZjN9NR3LXjnKKRw/.DXaZQNW.1XEottlCFIoKiDpIj.JGLJm";
							name  = "trash";
							quota = defaultQuota;
							catchAll = [
								domain
							];
						};
						"noreply@${domain}" = {
							hashedPassword = "$2b$05$TaKwoYmcmkAhsRRv6xG5wOkChcz50cB9BP6QPUDKNAcxMbrY6AeMK";
							name     = "noreply";
							quota    = defaultQuota;
							sendOnly = true;
						};
					};

					enableImap          = true;
					enableImapSsl       = true;
					enableSubmission    = true;
					enableSubmissionSsl = true;

					enableManageSieve = true;
					virusScanning     = false;

					certificateFile   = "/acme/live/${domain}/cert.pem";
					certificateScheme = "manual";
					keyFile           = "/acme/live/${domain}/privkey.pem";

					dkimKeyDirectory = "/var/dkim";
					indexDir         = "/var/lib/dovecot/indices";
					mailDirectory    = "/var/vmail";
					sieveDirectory   = "/var/sieve";

					mailboxes = let
						mkSpecialBox = specialUse: {
							${specialUse} = {
								inherit specialUse;
								auto = "subscribe";
							};
						};
					in builtins.foldl' (acc: box: acc // (mkSpecialBox box)) {} [
						"All"
						"Archive"
						"Drafts"
						"Junk"
						"Sent"
						"Trash"
					];

					dmarcReporting = {
						inherit domain;
						enable = true;
						organizationName = "voronind";
						# email = "noreply@${domain}";
					};

					# monitoring = {
					#   enable = true;
					#   alertAddress = "admin@${domain}";
					# };
				};

				services = {
					roundcube = {
						enable   = true;
						hostName = cfg.domain;
						dicts = with pkgs.aspellDicts; [
							en
							ru
						];
						plugins = [
							"managesieve"
						];
						extraConfig = util.trimTabs ''
							$config['smtp_server'] = "localhost:25";
							$config['smtp_auth_type'] = null;
							$config['smtp_user'] = "";
							$config['smtp_pass'] = "";
							# $config['smtp_user'] = "%u";
							# $config['smtp_pass'] = "%p";
						'';
					};

					nginx.virtualHosts.${cfg.domain} = {
						enableACME = false;
						forceSSL   = false;
					};
				};

				systemd = {
					services.autoexpunge = {
						description = "Delete old mail";
						serviceConfig = {
							Type = "oneshot";
						};
						path = [
							pkgs.dovecot
						];
						script = util.trimTabs ''
							doveadm expunge -A mailbox Junk SENTBEFORE 7d
							doveadm expunge -A mailbox Trash SENTBEFORE 30d
							doveadm expunge -u trash@voronind.com mailbox Inbox SENTBEFORE 30d
							doveadm purge -A
						'';
					};

					timers.autoexpunge = {
						timerConfig = {
							OnCalendar = "daily";
							Persistent = true;
							Unit       = "autoexpunge.service";
						};
						wantedBy = [
							"timers.target"
						];
					};
				};
			};
		};
	};
}