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

with lib;

let
  domaine = "nyanlout.re";

  sendMail = to: subject: message: pkgs.writeShellScriptBin "mail.sh" ''
    ${pkgs.system-sendmail}/bin/sendmail ${to} <<EOF
    From: root@nyanlout.re
    Subject: ${subject}
    ${message}
    EOF
  '';

  login_mail_alert = pkgs.writeShellScriptBin "mail_alert.sh" ''
    if [ "$PAM_TYPE" != "close_session" ] && [ "$PAM_USER" != "zfspaulfixe" ] && [ "$PAM_USER" != "synology" ] && [ "$PAM_USER" != "rezome" ]; then
      ${sendMail "paul@nyanlout.re" "SSH Login: $PAM_USER from $PAM_RHOST" "`env`"}/bin/mail.sh
    fi
  '';

  backup_mail_alert = sendMail "paul@nyanlout.re" "ERREUR: Sauvegarde Borg" "Impossible de terminer la sauvegarde. Merci de voir les logs";

  unstable = import <nixos-unstable> { };
in

{
  imports = [
    ../../services/python-ci.nix
    ../../services/sdtdserver.nix
    # /mnt/secrets/factorio_secrets.nix
    ./monitoring.nix
    ./medias.nix
    ./web.nix
  ];

  security.acme.certs = {
    "${domaine}" = {
      extraDomainNames = [
        "mail.${domaine}"
      ];
      postRun = ''
        systemctl reload dovecot2.service
      '';
    };
  };

  mailserver = {
    enable = true;
    fqdn = "mail.${domaine}";
    domains = [ domaine ];

    # A list of all login accounts. To create the password hashes, use
    # mkpasswd -m sha-512 "super secret password"
    loginAccounts = {
      "paul@${domaine}" = {
        hashedPassword = "$6$eGmy2W7kbkfHAh$/y.ZML4eYL/v14WaVwSIG2ulkUFKFk82uBmrYBDULLtqUR8hQD3/BQIrRiBtsloxrUSja8aZ.E7ypChO.OiOI/";
      };
      "claire@${domaine}" = {
        hashedPassword = "$6$Y.vlWP9./DX$NEQQOLzYftbHOvXDkKdBYFAjzIjh8mlpomDuQRq6qkkZijrdy/p6jSbrpBLhoWwVmj4j1OWekHU1f4C9xCNJk.";
      };
    };

    # Certificate setup
    certificateScheme = 1;
    certificateFile = "/var/lib/acme/${domaine}/fullchain.pem";
    keyFile = "/var/lib/acme/${domaine}/key.pem";

    # Enable IMAP and POP3
    enableImap = true;
    enablePop3 = true;
    enableImapSsl = true;
    enablePop3Ssl = true;

    # Enable the ManageSieve protocol
    enableManageSieve = true;
  };

  services = {
    postfix = {
      relayHost = "mailvps.nyanlout.re";
      relayPort = 587;
      config = {
        smtp_tls_cert_file = lib.mkForce "/var/lib/postfix/postfixrelay.crt";
        smtp_tls_key_file = lib.mkForce "/var/lib/postfix/postfixrelay.key";
      };
    };

    rspamd.workers.controller.extraConfig = ''
      secure_ip = ["0.0.0.0/0"];
    '';

    # redis.enable = true;

    # enable with nginx defult config
    logrotate.enable = true;

    fail2ban.enable = true;

    fstrim.enable = true;

    nfs.server = {
      enable = true;
      exports = ''
        /mnt/medias  10.30.0.0/16(ro,no_root_squash)
        /var/lib/minecraft  10.30.0.0/16(rw,no_root_squash)
      '';
      statdPort = 4000;
      lockdPort = 4001;
      mountdPort = 4002;
    };

    borgbackup.jobs = {
      loutre = {
        paths = [
          "/var/certs"
          "/var/dkim"
          "/var/lib/jellyfin"
          "/var/lib/gitea"
          "/var/lib/grafana"
          "/var/lib/jackett"
          "/mnt/borgsnap/postgresql"
          "/var/lib/radarr"
          "/var/lib/sonarr"
          "/var/lib/transmission"
          "/var/lib/airsonic"
          "/var/lib/hass"
          "/var/lib/opendkim"
          "/var/lib/slimserver"
          "/mnt/medias/musique"
          "/mnt/medias/torrent/lidarr"
          "/mnt/medias/torrent/musique"
          "/mnt/paul-home/paul"
          "/var/sieve"
          "/var/vmail"
          "/mnt/backup_loutre/amandoleen"
          "/mnt/secrets"
        ];
        exclude = [
          "/var/lib/radarr/.config/Radarr/radarr.db-wal"
          "/var/lib/radarr/.config/Radarr/radarr.db-shm"
        ];
        repo = "ssh://u306925@u306925.your-storagebox.de:23/./loutreos";
        environment = { BORG_RSH = "ssh -i /mnt/secrets/hetzner_ssh_key"; };
        encryption = {
          mode = "repokey-blake2";
          passCommand = "cat /mnt/secrets/borgbackup_loutre_encryption_pass";
        };
        startAt = "weekly";
        prune.keep = {
          within = "1d";
          weekly = 4;
          monthly = 12;
        };
        preHook = ''
          ${pkgs.zfs}/bin/zfs snapshot loutrepool/var/postgresql@borgsnap
          mkdir -p /mnt/borgsnap/postgresql
          ${config.security.wrapperDir}/mount -t zfs loutrepool/var/postgresql@borgsnap /mnt/borgsnap/postgresql
        '';
        readWritePaths = [ "/var/lib/postfix/queue/maildrop" ];
        postHook = ''
          ${config.security.wrapperDir}/umount /mnt/borgsnap/postgresql
          ${pkgs.zfs}/bin/zfs destroy loutrepool/var/postgresql@borgsnap
        '';
      };
    };

    borgbackup.repos = {
      diskstation = {
        authorizedKeys = [ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDllbxON66dBju7sMnhX8/E0VRo3+PDYvDsHP0/FK+h8JHol4+pouLmI7KIDKYOJmSuom283OqnyZOMqk+RShTwWIFm9hOd2R9aj45Zrd9jPW2APOCec/Epgogj0bwBnc0l2v6qxkxaBMgL5DnAQ+E00uvL1UQpK8c8j4GGiPlkWJD6Kf+pxmnfH1TIm+J2XCwl0oeCkSK/Frd8eM+wCraMSzoaGiEcfMz2jK8hxDWjDxX7epU0ELF22BVCuyN8cYRoFTnV88E38PlaqsOqD5ePkxk425gDh7j/C06f8QKgnasVH2diixo92kYSd7i/RmfeXDDwAD5xqUvODczEuIdt root@DiskStation" ];
        path = "/mnt/backup_loutre/diskstation_borg";
        user = "synology";
      };
      minecraft-rezome = {
        authorizedKeys = [ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDc1nGsSesW96k0DPMSt/chjvCrYmfgPgHG1hdUYB5x0pZPdOJaVRIlETWdoFlO+ViviC518B3TF7Qc3oJXPZMchJQl684Nukbc312juf+j9z/KT3dqD8YvKX6o5ynx1Dyq52ftrfkBAEAvzE0OfRljUPbwGBOM0dGRD4R1jbiHquTXpITlbgGTZymbwr4Jr9W9atgf5kHMiX7xOqMZcasDtUE8g+AG4ysHdpjOrBOUM9QeRbVP1bxEFP8xjqOOoET5tbkwektP4B2jaf+EHBPUy2lkwjVEKT6MaSlkJx/wMvUWp25kG9mrXgwUw1bgfOeZIsK6ztcki3l92BJQD9ip shame@minecraft.rezom.eu" ];
        path = "/mnt/backup_loutre/minecraft_rezome";
        user = "rezome";
      };
    };

    kresd = {
      enable = true;
    };

    home-assistant = {
      enable = true;
      extraComponents = [
        # Components required to complete the onboarding
        "met"
        "radio_browser"
      ];
      config = {
        default_config = {};
        homeassistant = {
          latitude = 48.60038;
          longitude = 7.74063;
          elevation = 146;
        };
        meteo_france = null;
        #influxdb = null;
        #config = null;
        #dhcp = null;
        #frontend = null;
        #history = null;
        http = {
          use_x_forwarded_for = true;
          trusted_proxies = [ "127.0.0.1" ];
        };
        #logbook = null;
        #map = null;
        #mobile_app = null;
        #person = null;
        #script = null;
        #sun = null;
        #system_health = null;
        zha = null;
        esphome = null;
        light = [
          {
            platform = "group";
            name = "Salon";
            entities = [
              "light.ikea_of_sweden_tradfri_bulb_e27_cws_806lm_e69e6dfe_level_light_color_on_off"
              "light.ikea_of_sweden_tradfri_bulb_e27_cws_806lm_43c25efe_level_light_color_on_off"
              "light.ikea_of_sweden_tradfri_bulb_e27_cws_806lm_3d0f76fe_level_light_color_on_off"
            ];
          }
        ];
        media_player = [
          {
            platform = "squeezebox";
            host = "10.30.0.1";
          }
        ];
        #tplink.switch = [
        #  { host = "10.30.50.7"; }
        #];
        #sensor = [
        #  {
        #    platform = "template";
        #    sensors = {
        #      serveur_amps = {
        #        friendly_name_template = "{{ states.switch.serveur.name}} Current";
        #        value_template = ''{{ states.switch.serveur.attributes["current_a"] | float }}'';
        #        unit_of_measurement = "A";
        #      };
        #      serveur_watts = {
        #        friendly_name_template = "{{ states.switch.serveur.name}} Current Consumption";
        #        value_template = ''{{ states.switch.serveur.attributes["current_power_w"] | float }}'';
        #        unit_of_measurement = "W";
        #      };
        #      serveur_total_kwh = {
        #        friendly_name_template = "{{ states.switch.serveur.name}} Total Consumption";
        #        value_template = ''{{ states.switch.serveur.attributes["total_energy_kwh"] | float }}'';
        #        unit_of_measurement = "kWh";
        #      };
        #      serveur_volts = {
        #        friendly_name_template = "{{ states.switch.serveur.name}} Voltage";
        #        value_template = ''{{ states.switch.serveur.attributes["voltage"] | float }}'';
        #        unit_of_measurement = "V";
        #      };
        #      serveur_today_kwh = {
        #        friendly_name_template = "{{ states.switch.serveur.name}} Today's Consumption";
        #        value_template = ''{{ states.switch.serveur.attributes["today_energy_kwh"] | float }}'';
        #        unit_of_measurement = "kWh";
        #      };
        #    };
        #  }
        #];
        #switch = [
        #  {
        #    platform = "wake_on_lan";
        #    name = "PC Fixe";
        #    mac = "b4:2e:99:ed:24:26";
        #    host = "10.30.135.71";
        #    broadcast_address = "10.30.255.255";
        #  }
        #];
        #device_tracker = [
        #  {
        #    platform = "ping";
        #    hosts = { telephone_paul = "10.30.50.2"; };
        #  }
        #];
        #scene = [
        #  {
        #    name = "Movie";
        #    icon = "mdi:movie-open";
        #    entities = {
        #      "light.salon" = {
        #        state = "on";
        #        xy_color = [0.299 0.115];
        #        brightness = 50;
        #      };
        #      "light.bande_led_tv" = {
        #        state = "on";
        #        effect = "Movie";
        #        brightness = 180;
        #      };
        #      "light.bande_led_bureau" = {
        #        state = "on";
        #        xy_color = [0.299 0.115];
        #        brightness = 130;
        #      };
        #    };
        #  }
        #  {
        #    name = "Home";
        #    icon = "mdi:home";
        #    entities = {
        #      "light.salon" = {
        #        state = "on";
        #        kelvin = 2700;
        #        brightness = 255;
        #      };
        #    };
        #  }
        #  {
        #    name = "Night";
        #    icon = "mdi:weather-night";
        #    entities = {
        #      "light.salon" = {
        #        state = "off";
        #      };
        #      "light.bande_led_tv" = {
        #        state = "off";
        #      };
        #      "light.bande_led_bureau" = {
        #        state = "off";
        #      };
        #      "light.chambre" = {
        #        state = "on";
        #        kelvin = 1900;
        #        brightness = 50;
        #      };
        #    };
        #  }
        #];
        #automation = let
        #  min_sun_elevation = 4;

        #  switch_chambre = {
        #    domain = "zha";
        #    platform = "device";
        #    device_id = "3329ecdcad244e5e8fc0f4b96d52ffe1";
        #  };

        #  switch_entree = {
        #    domain = "zha";
        #    platform = "device";
        #    device_id = "7cd814190ec543dba76a7aa7e7996c41";
        #  };

        #  remote = {
        #    domain = "zha";
        #    platform = "device";
        #    device_id = "d1230b76264e483388a8fdaad4f44143";
        #  };
        #in [
        #  # ENTREE

        #  {
        #    alias = "Aziz lumière";
        #    trigger = [
        #      {
        #        platform = "numeric_state";
        #        entity_id = "sun.sun";
        #        value_template = "{{ state.attributes.elevation }}";
        #        below = min_sun_elevation;
        #      }
        #    ];
        #    condition = [
        #      {
        #        condition = "state";
        #        entity_id = "person.paul";
        #        state = "home";
        #      }
        #      # Sun below max elevation
        #      {
        #        condition = "template";
        #        value_template = "{{ state_attr('sun.sun', 'elevation') < ${toString min_sun_elevation} }}";
        #      }
        #    ];
        #    action = {
        #      scene = "scene.home";
        #    };
        #  }
        #  {
        #    alias = "Aziz lumière switch";
        #    trigger = {
        #      type = "remote_button_short_press";
        #      subtype = "turn_on";
        #    } // switch_entree;
        #    action = {
        #      scene = "scene.home";
        #    };
        #  }
        #  {
        #    alias = "Adios";
        #    trigger = [
        #      {
        #        platform = "state";
        #        entity_id = "person.paul";
        #        to = "not_home";
        #      }
        #      ({
        #        type = "remote_button_short_press";
        #        subtype = "turn_off";
        #      } // switch_entree)
        #    ];
        #    action = [
        #      {
        #        service = "light.turn_off";
        #        entity_id = "all";
        #      }
        #      {
        #        service = "media_player.turn_off";
        #        entity_id = "all";
        #      }
        #    ];
        #  }

        #  # REMOTE

        #  {
        #    alias = "Button toggle";
        #    trigger = {
        #      type = "remote_button_short_press";
        #      subtype = "turn_on";
        #    } // remote;
        #    action = {
        #      choose = {
        #        conditions = {
        #          condition = "template";
        #          value_template = ''
        #            {% set domain = 'light' %}
        #            {% set state = 'off' %}
        #            {{ states[domain] | count == states[domain] | selectattr('state','eq',state) | list | count }}
        #          '';
        #        };
        #        sequence = {
        #          scene = "scene.home";
        #        };
        #      };
        #      default = {
        #        service = "light.turn_off";
        #        entity_id = "all";
        #      };
        #    };
        #  }
        #  {
        #    alias = "Button scene movie";
        #    trigger = {
        #      type = "remote_button_short_press";
        #      subtype = "right";
        #    } // remote;
        #    action = {
        #      scene = "scene.movie";
        #    };
        #  }
        #  {
        #    alias = "Button scene home";
        #    trigger = {
        #      type = "remote_button_short_press";
        #      subtype = "left";
        #    } // remote;
        #    action = {
        #      scene = "scene.home";
        #    };
        #  }
        #  {
        #    alias = "Button light up";
        #    trigger = {
        #      type = "remote_button_short_press";
        #      subtype = "dim_up";
        #    } // remote;
        #    action = {
        #      service = "light.turn_on";
        #      entity_id = "light.salon";
        #      data = {
        #        brightness_step = 25;
        #      };
        #    };
        #  }
        #  {
        #    alias = "Button light down";
        #    trigger = {
        #      type = "remote_button_short_press";
        #      subtype = "dim_down";
        #    } // remote;
        #    action = {
        #      service = "light.turn_on";
        #      entity_id = "light.salon";
        #      data = {
        #        brightness_step = -25;
        #      };
        #    };
        #  }

        #  # CHAMBRE

        #  {
        #    alias = "Button scene night";
        #    trigger = {
        #      type = "remote_button_short_press";
        #      subtype = "turn_on";
        #    } // switch_chambre;
        #    action = {
        #      scene = "scene.night";
        #    };
        #  }
        #  {
        #    alias = "Button scene dodo";
        #    trigger = {
        #      type = "remote_button_short_press";
        #      subtype = "turn_off";
        #    } // switch_chambre;
        #    action = {
        #      service = "light.turn_off";
        #      entity_id = "all";
        #    };
        #  }
        #  {
        #    alias = "Button scene lumière chambre ON";
        #    trigger = {
        #      type = "remote_button_long_press";
        #      subtype = "dim_up";
        #    } // switch_chambre;
        #    action = {
        #      service = "light.turn_on";
        #      entity_id = "light.chambre";
        #    };
        #  }
        #  {
        #    alias = "Button scene lumière chambre OFF";
        #    trigger = {
        #      type = "remote_button_long_press";
        #      subtype = "dim_down";
        #    } // switch_chambre;
        #    action = {
        #      service = "light.turn_off";
        #      entity_id = "light.chambre";
        #    };
        #  }
        #];
      };
    };

    photoprism = {
      enable = true;
      originalsPath = "/mnt/backup_loutre/amandoleen/d/Users/Amand/Pictures";
      extraConfig = {
        PHOTOPRISM_AUTH_MODE = "public";
        PHOTOPRISM_READONLY = "1";
        PHOTOPRISM_SITE_URL = "https://photo.nyanlout.re/";
      };
    };
  };

  systemd.services."borgbackup-job-loutre".serviceConfig.TemporaryFileSystem = ["/mnt/borgsnap"];

  dogetipbot-telegram.enable = true;

  ipmihddtemp.enable = true;

  users.groups.nginx.members = [ "matrix-synapse" ];

  security.pam.services.sshd.text = pkgs.lib.mkDefault( pkgs.lib.mkAfter "session optional ${pkgs.pam}/lib/security/pam_exec.so seteuid ${login_mail_alert}/bin/mail_alert.sh" );

  networking = {
    firewall.interfaces.eno2.allowedTCPPorts = [
      3260
    ];

    firewall.allowedTCPPorts = [
      8448 # Matrix federation
      20 21 # FTP
    ];

    firewall.allowedTCPPortRanges = [
      { from = 64000; to = 65535; } # FTP
    ];
  };
}