# services/frigate.nix — Local NVR with AI object detection
# Consumes go2rtc streams; no MQTT / Home Assistant dependency.
# Authentication delegated to Authelia by hijacking the /auth location
# that the upstream Frigate module bakes into every nginx location block.
#
# The Frigate NixOS module hardcodes `auth_request /auth` + `auth_request_set`
# in every nginx location, reading $upstream_http_remote_role from the auth
# subrequest response. Authelia doesn't return a Remote-Role header, so we
# use a tiny local-only nginx wrapper (port 9092) that proxies to Authelia
# and injects `Remote-Role: admin` into the response. The /auth location
# then points at the wrapper instead of Authelia directly.
{ config, lib, ... }:
{
  config = lib.mkIf (config.networking.hostName == "FredOS-Mediaserver") {

    services.frigate = {
      enable = true;
      hostname = "frigate.nordhammer.it";
      checkConfig = false;

      settings = {
        mqtt.enabled = false;
        detectors.cpu1 = {
          type = "cpu";
          num_threads = 8;
        };
        proxy.header_map = {
          user = "Remote-User";
          role = "Remote-Role";
        };

        cameras.kids_bedroom = {
          enabled = true;
          ffmpeg.inputs = [{
            path = "rtsp://127.0.0.1:8554/kids_bedroom";
            roles = [ "detect" "record" "audio" ];
          }];
          detect = {
            enabled = true;
            width = 1280;
            height = 720;
          };
          audio.enabled = true;
        };

        record = {
          enabled = true;
          retain = {
            days = 7;
            mode = "motion";
          };
        };

        snapshots = {
          enabled = true;
          retain.default = 14;
        };
      };
    };

    # Local-only auth wrapper: proxies to Authelia and adds Remote-Role header
    # so that auth_request_set $role $upstream_http_remote_role gets "admin".
    services.nginx.virtualHosts."frigate-auth-wrapper" = {
      listen = [{ addr = "127.0.0.1"; port = 9092; }];
      locations."/" = {
        proxyPass = "http://127.0.0.1:9091/api/verify";
        extraConfig = ''
          proxy_pass_request_body off;
          proxy_set_header Content-Length "";
          proxy_set_header X-Original-URL $http_x_original_url;
          proxy_set_header X-Forwarded-Method $http_x_forwarded_method;
          proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
          proxy_set_header X-Forwarded-Host $http_x_forwarded_host;
          proxy_set_header X-Forwarded-Uri $http_x_forwarded_uri;
          proxy_set_header X-Forwarded-For $http_x_forwarded_for;
          add_header Remote-Role admin always;
        '';
      };
    };

    services.nginx.virtualHosts."frigate.nordhammer.it" = {
      useACMEHost = "nordhammer.it";
      forceSSL = true;

      # Point /auth at the wrapper (9092) instead of Authelia (9091) directly.
      # The wrapper proxies to Authelia and injects Remote-Role: admin.
      locations."/auth" = lib.mkForce {
        proxyPass = "http://127.0.0.1:9092/";
        extraConfig = ''
          internal;
          proxy_pass_request_body off;
          proxy_set_header Content-Length "";
          proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
          proxy_set_header X-Forwarded-Method $request_method;
          proxy_set_header X-Forwarded-Proto $scheme;
          proxy_set_header X-Forwarded-Host $http_host;
          proxy_set_header X-Forwarded-Uri $request_uri;
          proxy_set_header X-Forwarded-For $remote_addr;
        '';
      };

      # The Frigate module serves the frontend from "/" without auth_request,
      # so unauthenticated users see a broken loading page instead of being
      # redirected to Authelia. Gate it behind auth too.
      locations."/".extraConfig = lib.mkAfter ''
        auth_request /auth;
      '';

      # Redirect 401 → Authelia login portal
      extraConfig = lib.mkAfter ''
        error_page 401 =302 https://auth.nordhammer.it/?rd=$scheme://$http_host$request_uri;
      '';
    };

    # GPU access for hardware-accelerated ffmpeg decoding
    users.users.frigate.extraGroups = [ "video" "render" ];
  };
}
