#
# NixOS-ish configuration for macOS machines, via nix-darwin.
#
# vim: et:ts=2:sw=2:
#
{ config, pkgs, ... }:

{
  # Allow non-free packages.
  nixpkgs.config.allowUnfree = true;

  # Our core user account.
  users.users.deprekated = {
    name = "deprekated";
    home = "/Users/deprekated";
  };

  # Use our default configuration.nix scheme.
  environment.darwinConfig = "/Users/deprekated/dotfiles/nixos/configuration.nix";

  # Use xonsh as our default shell.
  environment.loginShell = "/run/current-system/sw/bin/xonsh";

  # Xonsh is currently broken in unstable.
  # Add a harmless workaround to all of our systems.
  imports = [
    ./overlays/always-wrap-xonsh.nix
  ];

  # Use macOS's terminfo directories by default.
  # Squish our user in there, too.
  environment.variables.TERMINFO_DIRS = [
    "/usr/share/terminfo"
    "/Users/deprekated/.terminfo"
  ];

  # Auto upgrade nix package and the daemon service.
  services.nix-daemon.enable = true;

  # Use font configuration like in normal NixOS.
  fonts.fontDir.enable = true;

  # Allow use of e.g. 'nix search'.
  nix.settings.trusted-users = [ "deprekated" ];
  nix.settings.experimental-features = [
    "nix-command"
    "flakes"
  ];

  # Used for backwards compatibility, please read the changelog before changing.
  # $ darwin-rebuild changelog
  system.stateVersion = 4;

  #
  # macOS Configruation
  #
  system.defaults = {

    # OS-level configuration.
    NSGlobalDomain = {

      # Always use dark mode.
      AppleInterfaceStyle = "Dark";

      # Don't use two-finger swipes as 'back' and 'forward'.
      AppleEnableSwipeNavigateWithScrolls = false;
      AppleEnableMouseSwipeNavigateWithScrolls = false;

      # Allow full-OS keyboard control.
      AppleKeyboardUIMode = 3;

      # Disable press-and-hold for keys in favor of key repeat.
      ApplePressAndHoldEnabled = true;

      # Always show file extensions in Finder.
      AppleShowAllExtensions = true;

      # Speed up our key repeat.
      KeyRepeat = 2;
      InitialKeyRepeat = 10;

      # In general, have Apple not mess with our text.
      NSAutomaticCapitalizationEnabled = false;
      NSAutomaticDashSubstitutionEnabled = false;
      NSAutomaticPeriodSubstitutionEnabled = false;
      NSAutomaticQuoteSubstitutionEnabled = null;
      NSAutomaticSpellingCorrectionEnabled = false;

      # Don't automatically terminate inactive apps.
      NSDisableAutomaticTermination = false;

      # Always start with Save dialog panels expanded.
      NSNavPanelExpandedStateForSaveMode = true;
      NSNavPanelExpandedStateForSaveMode2 = true;

    };

    # More than just the dock configruation; also controls hot corners.
    dock = {
      autohide = true;

      # Put the dock on the left side of the screen, where we won't have to see it.
      orientation = "left";

      # Make the dock as tiny as possible, so we don't really see it.
      tilesize = 16;

      # Disable hot corners.
      wvous-bl-corner = 1;
      wvous-br-corner = 1;
      wvous-tl-corner = 1;
      wvous-tr-corner = 1;
    };

    finder = {
      # Necessary for true finder, instead of Finder embeds.
      AppleShowAllExtensions = true;

      # Don't show icons on the desktop.
      CreateDesktop = false;

      # Search in the current folder, instead of the whole mac.
      FXDefaultSearchScope = "SCcf";

      # Don't warn us on changing a file extension.
      FXEnableExtensionChangeWarning = false;

      # Defeault to the list view in Finder windows.
      FXPreferredViewStyle = "Nlsv";

      # Show the pathbar, which gives us breadcrumbs to the current folder.
      ShowPathbar = true;

      # Show the status bar, which has some useful metadata.
      ShowStatusBar = true;

      # Use the POSIX path in the finder title, rather than just the folder name.
      _FXShowPosixPathInTitle = true;

    };

    # Don't provide a Guest account.
    loginwindow.GuestEnabled = false;

    # Default to capturing screenshots in PNG.
    screencapture.type = "png";

    # TODO: validate and enable these
    CustomUserPreferences = {

      # Don't play system UI sounds.
      "NSGlobalDomain"."com.apple.sound.uiaudio.enabled" = 0;

      # Avoid creating .DS_Store files on network or USB volumes.
      "com.apple.desktopservices" = {
        DSDontWriteNetworkStores = true;
        DSDontWriteUSBStores = true;
      };

      ## Increase bluetooth sound quality at the cost of a little RAM.
      "com.apple.BluetoothAudioAgent"."Apple Bitpool Min (editable)" = 80;

      # Enable AirDrop over Ethernet
      "com.apple.NetworkBrowser".BrowseAllInterfaces = true;

      ## Don't show the touchbar or sidebar in Sidecar.
      "com.apple.sidecar.display" = {
        showTouchbar = false;
        showSidebar = false;
      };

      ## Finder options not yet internalized by Nix.
      "com.apple.finder" = {
        # Start new Finder sessions in our home folder.
        NewWindowTarget = "PfLo";
        NewWindowTargetPath = "file://\${HOME}";

        # Keep folders at the top of the Finder lists.
        _FXSortFoldersFirst = true;
      };

      ## Configure raycast so it's already set up for us.
      "com.raycast.macos" = {

        # Pretend this isn't a new install.
        onboardingCompleted = 1;
        onboarding_showTasksProgress = 0;
        amplitudePulseAnalyticsTracker_didSendInstallationEvent = 1;
        showGettingStartedLink = 0;
        raycastAnonymousId = "0FA9106D-B1ED-4CEE-AEE3-DD578111EEC1";
        raycastGlobalHotkey = "Command-49";
        raycastInstallationDate = "2023-07-21 20:00:16 +0000";
        raycastLoginItemAutoInstalled = "2023-07-21 20:00:17 +0000";

        # Misc configuration.
        showFavoritesInCompactMode = 0;
        raycastShouldFollowSystemAppearance = 0;
        raycastPreferredWindowMode = "compact";
        raycastCurrentThemeId = "bundled-raycast-dark";
        raycastCurrentThemeIdDarkAppearance = "bundled-raycast-dark";
      };

    };

    # We don't bother configuring spotlight, here, since
    # Raycast works much, much better with Nix, as it supports symliks.

  };

  # Use CapsLock as a second escape key.
  system.keyboard = {
    enableKeyMapping = true;
    remapCapsLockToEscape = true;
  };

  # Run extra initialization on provisioning.
  environment.extraInit = ''
    # Show the ~/Library folder
    chflags nohidden /home/deprekated/Library

    # Show the /Volumes folder
    chflags nohidden /Volumes
  '';

  # Fix Trelllis' database path by linking it into the environment.
  environment.postBuild = ''
    mkdir -p ''${out}/share/trellis
    ln -s ${pkgs.lib.lists.last pkgs.trellis.srcs} ''${out}/share/trellis/database
  '';

}
