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

let
  cfg = config.services.fleet-scheduler;
in
{
  options.services.fleet-scheduler = {
    enable = lib.mkEnableOption "fleet-scheduler service";

    chainfireEndpoint = lib.mkOption {
      type = lib.types.str;
      default = "http://127.0.0.1:7000";
      description = "ChainFire endpoint used by fleet-scheduler";
    };

    clusterNamespace = lib.mkOption {
      type = lib.types.str;
      default = "photoncloud";
      description = "Cluster namespace prefix";
    };

    clusterId = lib.mkOption {
      type = lib.types.str;
      description = "Cluster ID to reconcile";
      example = "plasmacloud-vm-cluster";
    };

    intervalSecs = lib.mkOption {
      type = lib.types.int;
      default = 15;
      description = "Scheduler reconciliation interval in seconds";
    };

    heartbeatTimeoutSecs = lib.mkOption {
      type = lib.types.int;
      default = 300;
      description = "Maximum node heartbeat age before a node becomes ineligible";
    };

    dryRun = lib.mkOption {
      type = lib.types.bool;
      default = false;
      description = "Log desired mutations without writing to ChainFire";
    };

    iamEndpoint = lib.mkOption {
      type = lib.types.nullOr lib.types.str;
      default = null;
      description = "IAM endpoint used for service publication";
    };

    fiberlbEndpoint = lib.mkOption {
      type = lib.types.nullOr lib.types.str;
      default = null;
      description = "FiberLB endpoint used for service publication";
    };

    flashdnsEndpoint = lib.mkOption {
      type = lib.types.nullOr lib.types.str;
      default = null;
      description = "FlashDNS endpoint used for service publication";
    };

    publishAddress = lib.mkOption {
      type = lib.types.nullOr lib.types.str;
      default = null;
      description = "Fallback address published into DNS when FiberLB does not allocate a VIP";
    };

    defaultOrgId = lib.mkOption {
      type = lib.types.str;
      default = "default-org";
      description = "Default org_id used when service publication omits one";
    };

    defaultProjectId = lib.mkOption {
      type = lib.types.str;
      default = "default-project";
      description = "Default project_id used when service publication omits one";
    };

    controllerPrincipalId = lib.mkOption {
      type = lib.types.str;
      default = "fleet-scheduler";
      description = "Service-account principal used for publication controller tokens";
    };

    package = lib.mkOption {
      type = lib.types.package;
      default = pkgs.fleet-scheduler or (throw "fleet-scheduler package not found");
      description = "Package to use for fleet-scheduler";
    };
  };

  config = lib.mkIf cfg.enable {
    users.users.fleet-scheduler = {
      isSystemUser = true;
      group = "fleet-scheduler";
      description = "Fleet scheduler service user";
      home = "/var/lib/fleet-scheduler";
    };

    users.groups.fleet-scheduler = { };

    systemd.services.fleet-scheduler = {
      description = "PhotonCloud Fleet Scheduler";
      wantedBy = [ "multi-user.target" ];
      after = [ "network-online.target" ];
      wants = [ "network-online.target" ];

      serviceConfig = {
        Type = "simple";
        User = "fleet-scheduler";
        Group = "fleet-scheduler";
        Restart = "on-failure";
        RestartSec = "5s";
        StateDirectory = "fleet-scheduler";
        StateDirectoryMode = "0750";
        NoNewPrivileges = true;
        PrivateTmp = true;
        ProtectSystem = "strict";
        ProtectHome = true;
        ExecStart = ''
          ${cfg.package}/bin/fleet-scheduler \
            --chainfire-endpoint ${lib.escapeShellArg cfg.chainfireEndpoint} \
            --cluster-namespace ${lib.escapeShellArg cfg.clusterNamespace} \
            --cluster-id ${lib.escapeShellArg cfg.clusterId} \
            --interval-secs ${toString cfg.intervalSecs} \
            --heartbeat-timeout-secs ${toString cfg.heartbeatTimeoutSecs} \
            ${lib.optionalString (cfg.iamEndpoint != null) "--iam-endpoint ${lib.escapeShellArg cfg.iamEndpoint}"} \
            ${lib.optionalString (cfg.fiberlbEndpoint != null) "--fiberlb-endpoint ${lib.escapeShellArg cfg.fiberlbEndpoint}"} \
            ${lib.optionalString (cfg.flashdnsEndpoint != null) "--flashdns-endpoint ${lib.escapeShellArg cfg.flashdnsEndpoint}"} \
            ${lib.optionalString (cfg.publishAddress != null) "--publish-address ${lib.escapeShellArg cfg.publishAddress}"} \
            --default-org-id ${lib.escapeShellArg cfg.defaultOrgId} \
            --default-project-id ${lib.escapeShellArg cfg.defaultProjectId} \
            --controller-principal-id ${lib.escapeShellArg cfg.controllerPrincipalId} \
            ${lib.optionalString cfg.dryRun "--dry-run"}
        '';
      };
    };
  };
}
