{ lib, pkgs, cfg, models, allPhones }:

let
  # Does any provisioned phone on this extension support intercom?
  extensionHasIntercom = ext:
    lib.any (phone: phone.extension == ext && models.${phone.model}.hasIntercom)
      (lib.attrValues allPhones);

  personContacts = lib.mapAttrsToList (_key: person:
    lib.filterAttrs (_: v: v != null) {
      displayName   = person.displayName;
      extension     = person.extension;
      sipUsernames  = lib.attrNames person.phones;
      intercomExtension =
        if cfg.intercomPrefix != null && extensionHasIntercom person.extension
          then "${cfg.intercomPrefix}${person.extension}"
          else null;
      mailboxCheckExtension =
        if person.mailbox then "*97" else null;
    }
  ) cfg.persons;

  sharedPhoneContacts = lib.mapAttrsToList (key: phone:
    lib.filterAttrs (_: v: v != null) {
      displayName  = phone.displayName;
      extension    = phone.extension;
      sipUsernames = [ key ];
      intercomExtension =
        if cfg.intercomPrefix != null && models.${phone.model}.hasIntercom
          then "${cfg.intercomPrefix}${phone.extension}"
          else null;
    }
  ) cfg.sharedPhones;

  specialExtensions = lib.mapAttrsToList (ext: extCfg: {
    displayName = extCfg.displayName;
    extension   = ext;
    mode        = extCfg.mode;
  }) cfg.extensions;

  directory = {
    version           = 1;
    contacts          = personContacts ++ sharedPhoneContacts;
    specialExtensions = specialExtensions;
  } // lib.optionalAttrs (cfg.sharedMailbox != null) {
    sharedMailbox = {
      inherit (cfg.sharedMailbox) displayName checkExtension;
    };
  };

in
  pkgs.writeText "contacts.json" (builtins.toJSON directory)
