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

with lib;

let
  cfg = config.nix-nos.bgp;

  # BGP peer type
  peerType = types.submodule {
    options = {
      address = mkOption {
        type = types.str;
        description = "Peer IP address";
        example = "192.168.1.1";
      };

      asn = mkOption {
        type = types.int;
        description = "Peer AS number";
        example = 65001;
      };

      description = mkOption {
        type = types.str;
        default = "";
        description = "Human-readable peer description";
      };
    };
  };

  # BGP announcement type
  announcementType = types.submodule {
    options = {
      prefix = mkOption {
        type = types.str;
        description = "IP prefix to announce in CIDR notation";
        example = "10.0.0.0/24";
      };

      nexthop = mkOption {
        type = types.nullOr types.str;
        default = null;
        description = "Override next-hop IP address";
      };
    };
  };

in {
  imports = [
    ./bird.nix
    ./gobgp.nix
  ];

  options.nix-nos.bgp = {
    enable = mkEnableOption "BGP routing";

    backend = mkOption {
      type = types.enum [ "bird" "gobgp" ];
      default = "bird";
      description = "BGP daemon backend to use";
    };

    asn = mkOption {
      type = types.int;
      description = "Local AS number";
      example = 64512;
    };

    routerId = mkOption {
      type = types.str;
      description = "BGP router ID (typically an IP address)";
      example = "10.0.0.1";
    };

    peers = mkOption {
      type = types.listOf peerType;
      default = [];
      description = "BGP peer configurations";
    };

    announcements = mkOption {
      type = types.listOf announcementType;
      default = [];
      description = "Prefixes to announce to BGP peers";
    };
  };

  config = mkIf (config.nix-nos.enable && cfg.enable) {
    # Assertions
    assertions = [
      {
        assertion = cfg.asn > 0 && cfg.asn < 4294967296;
        message = "BGP ASN must be between 1 and 4294967295";
      }
      {
        assertion = cfg.routerId != "";
        message = "BGP router ID must be configured";
      }
    ];

    # Backend-specific configuration is handled by bird.nix and gobgp.nix
  };
}
