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

with lib;

let
  cfg = config.nix-nos.bgp;

  # Generate GoBGP configuration
  gobgpConfig = pkgs.writeText "gobgpd.conf" (builtins.toJSON {
    global = {
      config = {
        as = cfg.asn;
        router-id = cfg.routerId;
      };
    };

    neighbors = map (peer: {
      config = {
        neighbor-address = peer.address;
        peer-as = peer.asn;
        description = if peer.description != "" then peer.description else "BGP peer ${peer.address}";
      };
    }) cfg.peers;

    defined-sets = {
      prefix-sets = [
        {
          prefix-set-name = "nix-nos-announcements";
          prefix-list = map (ann: {
            ip-prefix = ann.prefix;
          }) cfg.announcements;
        }
      ];
    };

    policy-definitions = [
      {
        name = "export-announcements";
        statements = [
          {
            conditions = {
              match-prefix-set = {
                prefix-set = "nix-nos-announcements";
              };
            };
            actions = {
              route-disposition = "accept-route";
            };
          }
        ];
      }
    ];
  });

in {
  config = mkIf (config.nix-nos.enable && cfg.enable && cfg.backend == "gobgp") {
    # Install GoBGP package
    environment.systemPackages = [ pkgs.gobgp pkgs.gobgpd ];

    # GoBGP systemd service
    systemd.services.gobgpd = {
      description = "GoBGP Routing Daemon";
      after = [ "network.target" ];
      wantedBy = [ "multi-user.target" ];

      serviceConfig = {
        Type = "simple";
        ExecStart = "${pkgs.gobgpd}/bin/gobgpd -f ${gobgpConfig}";
        Restart = "on-failure";
        RestartSec = "5s";
      };
    };

    # Enable IP forwarding for BGP
    boot.kernel.sysctl = {
      "net.ipv4.ip_forward" = 1;
    };

    # Add announcements as static routes
    networking.localCommands = mkIf (cfg.announcements != []) ''
      ${concatMapStringsSep "\n" (ann:
        let
          parts = splitString "/" ann.prefix;
          ip = elemAt parts 0;
        in
        "${pkgs.iproute2}/bin/ip route add ${ann.prefix} ${if ann.nexthop != null then "via ${ann.nexthop}" else "blackhole"}"
      ) cfg.announcements}
    '';
  };
}
