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

{ depot, lib, pkgs, ... }@args:
let
  inherit (builtins) foldl' mapAttrs;
  baseModule = name: { ... }: {
    _module.args = args // {
      rebuilder = rebuilder name;
    };
  };
  systemFor = systemName: config:
    (depot.third_party.nixeval {
      system = builtins.currentSystem;
      modules = [ (baseModule systemName) (args: { imports = [ lib/common.nix config ]; }) ];
    });
  systems = [
    "porcorosso"
    "howl"
    "clouvider-fra01"
    "totoro"
    "swann"
    "clouvider-lon01"
    "etheroute-lon01"
    "blade-janeway"
    "blade-tuvok"
    "blade-paris"
    "blade-torres"
    "blade-chakotay"
    "blade-kim"
    "frantech-lux01"
    "frantech-nyc01"
    "frantech-las01"
    "bvm-nixosmgmt"
    "bvm-twitterchiver"
    "bvm-prosody"
    "bvm-ipfs"
    "bvm-matrix"
    "bvm-minecraft"
    "bvm-netbox"
    "bvm-radius"
    "bvm-heptapod"
    "bvm-logger"
  ];
  rebuilder = system: (import ./lib/rebuilder.nix (args // { system = system; }));
  systemCfgs = lib.genAttrs systems
    (name: import (./. + "/${name}"));
  evaledSystems = mapAttrs systemFor systemCfgs;
  systemDrvs = mapAttrs (_: sys: sys.config.system.build.toplevel) evaledSystems;
  systemTailscaleIPs = lib.mapAttrs' (n: v: lib.nameValuePair v [n]) (lib.filterAttrs (n: v: v != null) (mapAttrs (_: sys: sys.config.my.ip.tailscale) evaledSystems));

  systemExporters = let
    exportersForSystem = sysName: sys: let
      mkExporter = exporterName: exporterPort: let jobName = "${sysName}/exporters/${exporterName}"; in lib.nameValuePair jobName {
        job_name = jobName;
        static_configs = [{
          targets = ["${sysName}:${toString exporterPort}"];
          labels = {
            system = sysName;
            exporter = exporterName;
          };
        }];
      };
      stockExporters = lib.mapAttrsToList (exporterName: exporter: mkExporter exporterName exporter.port) (lib.filterAttrs (exporterName: exporter: exporterName != "snmp" && exporter.enable) sys.config.services.prometheus.exporters);
      customExporters = lib.mapAttrsToList mkExporter sys.config.my.prometheus.additionalExporterPorts;
    in
      stockExporters ++ customExporters;
  in
    builtins.listToAttrs (builtins.concatLists (lib.mapAttrsToList exportersForSystem evaledSystems));
  scrapeJournalHosts =
    lib.filterAttrs (n: v: v.enable) (lib.mapAttrs (n: v: v.config.my.scrapeJournal) evaledSystems);

  netbootSystem = systemFor "netboot" (import ./netboot);
  installcdSystem = systemFor "installcd" (import ./installcd);
in systemDrvs // {
  systems = systemDrvs;
  systemConfigs = evaledSystems;
  systemExporters = systemExporters;
  tailscaleIPs = systemTailscaleIPs;
  scrapeJournalHosts = scrapeJournalHosts;

  netboot = netbootSystem.config.system.build.pixiecore;
  installcd = installcdSystem.config.system.build.isoImage;

  systemPathJSON = pkgs.writeText "systems.json" (builtins.toJSON systemDrvs);
}