{ config, pkgs, ... }:

let
  lat = "51.081";
  lon = "13.728";
  altitude = "150";

  makeMlatClientService = args: {
    wantedBy = [ "multi-user.target" ];
    requires = [ "dump1090.service" ];
    serviceConfig = {
      User = "mlat-client";
      Group = "adsb";
      ProtectHome = true;
      Restart = "always";
      RestartSec = "10s";
    };
    path = with pkgs; [ mlat-client ];
    script = ''
      mlat-client --input-type beast --input-connect localhost:30005 --lat ${lat} --lon ${lon} --alt ${altitude} ${args}
    '';
  };
in {
  boot.blacklistedKernelModules = [
    # no watching TV intended
    "dvb_usb_rtl28xxu"
  ];

  networking.firewall.allowedTCPPorts = [
    # dump1090
    30001
    30002
    30003
    30004
    30005
  ];

  environment.systemPackages = with pkgs; [
    dump1090
  ];

  sops.secrets = {
    "chaos-consulting/user".owner = "mlat-client";
  };

  users = {
    groups.adsb = {};
    users = {
      dump1090-influxdb = {
        isSystemUser = true;
        group = "adsb";
      };
      mlat-client = {
        isSystemUser = true;
        group = "adsb";
      };
      dump1090 = {
        isSystemUser = true;
        group = "adsb";
      };
      sbs2json = {
        isSystemUser = true;
        group = "adsb";
      };
    };
  };

  systemd.services = {
    dump1090-influxdb = {
      wantedBy = [ "multi-user.target" ];
      requires = [ "dump1090.service" ];
      serviceConfig = {
        ExecStart = "${pkgs.dump1090-influxdb}/bin/dump1090-influxdb";
        User = "dump1090-influxdb";
        Group = "adsb";
        ProtectSystem = "full";
        ProtectHome = true;
        Restart = "always";
        RestartSec = "10s";
      };
    };

    feed-chaos-consulting = {
      wantedBy = [ "multi-user.target" ];
      requires = [ "sbs2json.service" ];
      serviceConfig = {
        User = "mlat-client";
        Group = "adsb";
        ProtectHome = true;
        Restart = "always";
        RestartSec = "10s";
      };
      path = with pkgs; [ curl gzip ];
      script = ''
        while (
          echo '{"now":'
          date +%s
          echo ',"aircraft":'
          curl -s http://localhost:8080/data.json
          echo '}'
        ) \
            | gzip -c \
            | curl -s \
              -u "$(cat ${config.sops.secrets."chaos-consulting/user".path})" \
              -X POST \
              -H "Content-type: application/json" \
              -H "Content-encoding: gzip" \
              --data-binary @- \
              https://adsb.chaos-consulting.de/aircraftin/index.php
        do
          sleep 1
        done
      '';
    };

    # Feeds adsbexchange.com, test at https://www.adsbexchange.com/myip/
    mlat-client-adsbexchange = makeMlatClientService "--server feed.adsbexchange.com:31090 --user C3D2";
    # Feeds https://adsb.chaos-consulting.de/map/
    mlat-client-chaos-consulting = makeMlatClientService "--server ${config.services.stunnel.clients.mlat-client-chaos-consulting.accept} --user \"$(cat ${config.sops.secrets."chaos-consulting/user".path})\"";

    dump1090 = {
      wantedBy = [ "multi-user.target" ];
      serviceConfig = {
        ExecStart = "${pkgs.dump1090}/bin/dump1090 --modeac --forward-mlat --quiet --lon ${lon} --lat ${lat} --net --net-ro-port 30002 --net-sbs-port 30003 --net-bo-port 30005";
        User = "dump1090";
        Group = "adsb";
        ProtectSystem = "full";
        ProtectHome = true;
        Restart = "always";
        RestartSec = "10s";
      };
    };

    # SHIM because dump1090 has no web server like dump1090
    sbs2json = {
      wantedBy = [ "multi-user.target" ];
      requires = [ "dump1090.service" ];
      serviceConfig = {
        ExecStart = "${pkgs.heliwatch.http-json}/bin/http-json";
        User = "sbs2json";
        Group = "adsb";
        ProtectSystem = "full";
        ProtectHome = true;
        Restart = "always";
        RestartSec = "10s";
      };
    };
  };

  services = {
    collectd.plugins.exec = ''
      Exec "${config.services.collectd.user}" "${pkgs.heliwatch.collectd-stats}/bin/collectd-stats"
    '';
    # mlat-client-chaos-consulting needs ssl
    stunnel = {
      enable = true;
      clients.mlat-client-chaos-consulting = {
        accept = "127.0.0.1:3334";
        connect = "mlat.chaos-consulting.de:3334";
        verifyChain = false;
        verifyPeer = false;
      };
    };
  };
}
