# SPDX-FileCopyrightText: 2024 Luke Granger-Brown <depot@lukegb.com>
#
# SPDX-License-Identifier: Apache-2.0

{ depot, lib, pkgs, config, ... }:
{
  imports = [
    ../lib/bgp.nix
  ];

  services.lukegbgp = let
    local.asn = 205479;
  in {
    enable = true;
    config = {
      local = {
        routerID = "195.74.55.21";
      };
      export.v4 = [ "92.118.28.0/22" ];
      export.v6 = [ "2a09:a442:1000::/48" "2a09:a442::/48" ];

      internal.export.v4 = [ "92.118.30.251/32" ];
      internal.export.v4Extra = ''
        route 92.118.30.2/31 via "wg-swann-ee";
        route 92.118.30.4/31 via "wg-swann-gnet";
      '';
      internal.export.v6 = [ "2a09:a442:1000::/48" "2a09:a442::/48" ];
      internal.export.v6Extra = ''
        route 2a09:a442::2:0/112 via "wg-swann-ee";
        route 2a09:a442::3:0/112 via "wg-swann-gnet";
      '';

      peering = let
        base = [{
          local.asn = 205479;
        }];
        link.velox1 = base ++ [{
          local.v4 = "195.74.55.21";
          local.v6 = "2a03:ee40:8080:9:1::2";
        }];
        link.velox2 = base ++ [{
          local.v4 = "195.74.55.23";
          local.v6 = "2a03:ee40:8080:9:2::2";
        }];
        link.linx = base ++ [{
          local.v4 = "195.66.224.58";
          local.v6 = "2001:7f8:4::3:22a7:1";
          #remote.pref_src.v4 = "195.74.55.21";
          #remote.pref_src.v6 = "2a03:ee40:8080:9:1::2";
          remote.pref_src.v4 = "92.118.30.251";
          remote.pref_src.v6 = "2a09:a442:1000::";
        }];
        peer.velox.remote = {
          asn = 3170;
          export_community = 4001;
          bgp_local_pref = 101;
        };
        peer.swann = {
          remote.bfd = true;
          remote.asn = 205479;
          remote.must_be_next_hop = false;
          remote.export_community = 10;
        };
      in {
        swann_ee = lib.mkMerge (base ++ [peer.swann {
          local.v4 = "92.118.30.3";
          local.v6 = "2a09:a442::2:2";
          remote.routers = [{
            enabled = true;
            v4 = "92.118.30.2";
            v6 = "2a09:a442::2:1";
          }];
          remote.bgp_local_pref = 10;
        }]);
        swann_gnet = lib.mkMerge (base ++ [peer.swann {
          local.v4 = "92.118.30.5";
          local.v6 = "2a09:a442::3:2";
          remote.routers = [{
            enabled = true;
            v4 = "92.118.30.4";
            v6 = "2a09:a442::3:1";
          }];
        }]);
        veloxserv1 = lib.mkMerge (link.velox1 ++ [peer.velox {
          remote.routers = [{
            enabled = true;
            v4 = "195.74.55.20";
            v6 = "2a03:ee40:8080:9:1::1";
          }];
        }]);
        veloxserv2 = lib.mkMerge (link.velox2 ++ [peer.velox {
          remote.routers = [{
            enabled = true;
            v4 = "195.74.55.22";
            v6 = "2a03:ee40:8080:9:2::1";
          }];
        }]);
        linxcollector = lib.mkMerge (link.linx ++ [{
          remote = {
            asn = 5459;
            export_community = 5000;
            routers = [{
              enabled = true;
              v4 = "195.66.224.254";
              v6 = "2001:7f8:4::1553:1";
            }];
            prefix_limit.v4 = 0;
            prefix_limit.v6 = 0;
            is_route_collector = false;
          };
        }]);
        linx = lib.mkMerge (link.linx ++ [{
          remote = {
            asn = 8714;
            export_community = 5001;
            routers = [{
              enabled = true;
              v4 = "195.66.225.230";
              v6 = "2001:7f8:4::220a:1";
            } {
              enabled = true;
              v4 = "195.66.225.231";
              v6 = "2001:7f8:4::220a:2";
            }];
            bgp_local_pref = 109;
            must_be_next_hop = false;
          };
        }]);
        facebook = lib.mkMerge (link.linx ++ [{
          remote = {
            asn = 32934;
            export_community = 5002;
            routers = [{
              enabled = true;
              v4 = "195.66.225.69";
              v6 = "2001:7f8:4::80a6:1";
            } {
              enabled = true;
              v4 = "195.66.225.121";
              v6 = "2001:7f8:4::80a6:2";
            } {
              enabled = true;
              v4 = "195.66.227.19";
              v6 = "2001:7f8:4::80a6:5";
            } {
              enabled = true;
              v4 = "195.66.226.140";
              v6 = "2001:7f8:4::80a6:3";
            }];
            bgp_local_pref = 120;
            prefix_limit.v4 = 100;
            prefix_limit.v6 = 100;
          };
        }]);
        openpeering = lib.mkMerge (link.linx ++ [{
          remote = {
            asn = 20562;
            export_community = 5003;
            passive = true;  # pending
            routers = [{
              enabled = true;
              v4 = "195.66.225.53";
              v6 = "2001:7f8:4::5052:1";
            }];
            bgp_local_pref = 110;
            prefix_limit.v4 = 16000;
            prefix_limit.v6 = 3000;
          };
        }]);
        freetransitnet = lib.mkMerge (link.linx ++ [{
          remote = {
            asn = 212895;
            export_community = 5004;
            passive = true;  # pending v6
            bgp_local_pref = 100;
            routers = [{
              enabled = true;
              v4 = "195.66.225.105";
              v6 = "2001:7f8:4::3:3f9f:2";
            }];
          };
        }]);
        he = lib.mkMerge (link.linx ++ [{
          remote = {
            asn = 6939;
            export_community = 5005;
            routers = [{
              enabled = true;
              v4 = "195.66.224.21";
              v6 = "2001:7f8:4::1b1b:1";
            }];
            bgp_local_pref = 108;
            prefix_limit.v4 = 176000;
            prefix_limit.v6 = 156000;
          };
        }]);
        clouvider = lib.mkMerge (link.linx ++ [{
          remote = {
            asn = 62240;
            export_community = 5006;
            passive = true;  # pending
            routers = [{
              enabled = true;
              v4 = "195.66.227.14";
              v6 = "2001:7f8:4::f320:1";
            }];
            bgp_local_pref = 120;
            prefix_limit.v4 = 1000;
            prefix_limit.v6 = 1000;
          };
        }]);
        google = lib.mkMerge (link.linx ++ [{
          remote = {
            asn = 15169;
            export_community = 5007;
            routers = [{
              enabled = true;
              v4 = "195.66.224.125";
              v6 = "2001:7f8:4::3b41:1";
            }];
            bgp_local_pref = 120;
            prefix_limit.v4 = 15000;
            prefix_limit.v6 = 10000;
          };
        }]);
        cloudflare = lib.mkMerge (link.linx ++ [{
          remote = {
            asn = 13335;
            export_community = 5008;
            routers = [{
              enabled = true;
              v4 = "195.66.225.179";
              v6 = "2001:7f8:4::3417:1";
            } {
              enabled = true;
              v4 = "195.66.227.207";
              v6 = "2001:7f8:4::3417:2";
            }];
            bgp_local_pref = 120;
            prefix_limit.v4 = 20000;
            prefix_limit.v6 = 2000;
          };
        }]);
        fastly = lib.mkMerge (link.linx ++ [{
          remote = {
            asn = 54113;
            export_community = 5009;
            routers = [{
              enabled = true;
              v4 = "195.66.225.91";
              v6 = "2001:7f8:4::d361:1";
            } {
              enabled = true;
              v4 = "195.66.227.114";
              v6 = "2001:7f8:4::d361:2";
            }];
            bgp_local_pref = 120;
            prefix_limit.v4 = 250;
            prefix_limit.v6 = 250;
          };
        }]);
        ovh = lib.mkMerge (link.linx ++ [{
          remote = {
            asn = 16276;
            export_community = 5010;
            passive = true;  # pending
            routers = [{
              enabled = true;
              v4 = "195.66.224.220";
              v6 = "2001:7f8:4::3f94:1";
            } {
              enabled = true;
              v4 = "195.66.225.6";
              v6 = "2001:7f8:4::3f94:2";
            }];
            bgp_local_pref = 120;
            prefix_limit.v4 = 1000;
            prefix_limit.v6 = 200;
          };
        }]);
        arelion = lib.mkMerge (base ++ [{
          local = {
            v4 = "62.115.150.105";
            v6 = "2001:2035:0:1f7e::2";
          };
          remote = {
            asn = 1299;
            export_community = 7000;
            bgp_local_pref = 101;
            routers = [{
              v4 = "62.115.150.104";
              v6 = "2001:2035:0:1f7e::1";
            }];
          };
        }]);
      };
      bfd = ''
        interface "*" {
          min rx interval 10ms;
          min tx interval 50ms;
          idle tx interval 1s;
          multiplier 20;
        };
        neighbor 92.118.30.4;
        neighbor 2a09:a442::2:1;
        neighbor 92.118.30.6;
        neighbor 2a09:a442::3:1;
      '';
    };
  };
}