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

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

let
  nmFiles = builtins.attrNames (lib.filterAttrs (n: v: v == "regular" && lib.hasSuffix ".nmconnection" n) (builtins.readDir ./networkmanager));
  nmBits = lib.mkMerge (map (filename: {
    "NetworkManager/system-connections/${filename}" = {
      source = ./networkmanager + "/${filename}";
      mode = "0600";
    };
  }) nmFiles);

  boot-builder = pkgs.callPackage ./boot-builder.nix { };
  populate-boot-builder = pkgs.buildPackages.callPackage ./boot-builder.nix { };
in
{
  imports = [
    "${modulesPath}/installer/sd-card/sd-image.nix"
  ];

  fileSystems = {
    "/" = { device = "/dev/disk/by-label/NIXOS_SD"; fsType = "ext4"; };
    "/boot/firmware" = { device = "/dev/disk/by-label/FIRMWARE"; fsType = "vfat"; };
  };

  boot.kernelPackages = pkgs.linuxPackages_latest;
  boot.kernelParams = [ "console=ttyS0,115200n8" ];
  boot.initrd.kernelModules = [ "phy-mvebu-cp110-utmi" ];

  boot.kernel.sysctl = {
    "net.ipv4.ip_forward" = "1";
    "net.ipv6.conf.default.forwarding" = "1";
    "net.ipv6.conf.all.forwarding" = "1";
    "net.ipv6.conf.default.accept_ra_from_local" = "1";
    "net.ipv6.conf.all.accept_ra_from_local" = "1";
  };

  networking = {
    hostName = "kerrigan";
    domain = "as205479.net";
    hostId = "c424eeb8";
    useNetworkd = true;
    networkmanager = {
      enable = true;
      dns = "systemd-resolved";
      unmanaged = [ "*,except:type:gsm" ];
      extraConfig = ''
        [main]
        no-auto-default=*

        [logging]
        level=TRACE
        domains=ALL
      '';
    };
    nameservers = [
      "2001:4860:4860::8888"
      "2001:4860:4860::8844"
      "8.8.8.8"
      "8.8.4.4"
    ];
    interfaces.eth2.useDHCP = true;
  };
  users.users.lukegb.extraGroups = lib.mkAfter [ "networkmanager" ];
  my.systemType = "aarch64-linux";

  my.ip.tailscale = "100.110.212.70";
  my.ip.tailscale6 = "fd7a:115c:a1e0:ab12:4843:cd96:626e:d446";

  systemd.network.netdevs.br0 = {
    netdevConfig = {
      Name = "br0";
      Kind = "bridge";
    };
  };
  systemd.network.networks.br0 = {
    matchConfig.Name = "br0";
    networkConfig = {
      LinkLocalAddressing = "ipv6";
      Address = "10.42.0.1/24";
      IPForward = true;
      IPMasquerade = "ipv4";
      IPv6AcceptRA = true;
      DHCPServer = true;
    };
    ipv6AcceptRAConfig = {
      UseGateway = false;
      RouteMetric = 100;
    };
    dhcpServerConfig = {
      PoolOffset = 100;
      PoolSize = 100;
    };
  };
  systemd.network.networks.links-to-bridge = {
    matchConfig.Name = "lan*";
    networkConfig.Bridge = "br0";
  };

  systemd.services.ModemManager = {
    wantedBy = [ "network.target" ];
  };
  environment.etc = nmBits;

  sdImage.populateFirmwareCommands = lib.mkForce "";

  boot.loader.grub.enable = false;
  boot.loader.generic-extlinux-compatible.enable = lib.mkForce false;
  boot.consoleLogLevel = lib.mkDefault 7;
  system.build.installBootLoader = "${boot-builder} -g 10 -c";
  sdImage.populateRootCommands = lib.mkAfter ''
    mkdir -p ./files/boot
    ${populate-boot-builder} -c ${config.system.build.toplevel} -d ./files/boot
  '';

  services.radvd = {
    enable = true;
    config = ''
      interface br0 {
        IgnoreIfMissing on;
        AdvSendAdvert on;
        AdvLinkMTU 1280;

        prefix ffff:ffff:ffff:ffff::/64 {
          Base6Interface wwan0;
          AdvValidLifetime 600;
          AdvPreferredLifetime 300;
        };
      };
    '';
  };

  systemd.services."systemd-networkd-wait-online".wantedBy = lib.mkForce [];

  system.stateVersion = "23.05";
}