;; This file is my OS base
;; 
;; Author: Chris Cochrun
;; Email: chris@cochrun.xyz
;; 
;; License: GPLv3
;; 

(define-module (base)
  #:use-module (srfi srfi-1)
  #:use-module (gnu)
  #:use-module (gnu services)
  #:use-module (gnu services shepherd)
  #:use-module (gnu services dbus)
  #:use-module (gnu system)
  #:use-module (gnu system setuid)
  #:use-module (gnu system nss)
  #:use-module (gnu system shadow)
  #:use-module (gnu packages android)
  #:use-module (rosenthal packages wm)
  #:use-module (nongnu packages linux)
  #:use-module (nongnu system linux-initrd)
  #:export (base-system-packages base-operating-system base-system-services))

(use-service-modules cups desktop networking ssh xorg avahi
                     admin base nix dbus pm audio virtualization sysctl)

(use-package-modules nfs certs shells ssh linux bash emacs gnome networking wm fonts glib libusb
                     cups freedesktop file-systems version-control package-management)


(define etc-sudoers-config
  (plain-file "etc-sudoers-config"
              "Defaults  timestamp_timeout=480
root      ALL=(ALL) ALL
%wheel    ALL=(ALL) ALL
YOUR-USER-NAME  ALL=(ALL) NOPASSWD:/run/current-system/profile/bin/chvt,/run/current-system/profile/bin/loginctl"))


(define qmk-udev-rules
  (udev-rule
   "50-qmk.rules"
   (string-append
    "# Atmel DFU
### ATmega16U2
SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"03eb\", ATTRS{idProduct}==\"2fef\", TAG+=\"uaccess\"
### ATmega32U2
SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"03eb\", ATTRS{idProduct}==\"2ff0\", TAG+=\"uaccess\"
### ATmega16U4
SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"03eb\", ATTRS{idProduct}==\"2ff3\", TAG+=\"uaccess\"
### ATmega32U4
SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"03eb\", ATTRS{idProduct}==\"2ff4\", TAG+=\"uaccess\"
### AT90USB64
SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"03eb\", ATTRS{idProduct}==\"2ff9\", TAG+=\"uaccess\"
### AT90USB162
SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"03eb\", ATTRS{idProduct}==\"2ffa\", TAG+=\"uaccess\"
### AT90USB128
SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"03eb\", ATTRS{idProduct}==\"2ffb\", TAG+=\"uaccess\"

# Input Club
SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"1c11\", ATTRS{idProduct}==\"b007\", TAG+=\"uaccess\"

# STM32duino
SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"1eaf\", ATTRS{idProduct}==\"0003\", TAG+=\"uaccess\"
# STM32 DFU
SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"df11\", TAG+=\"uaccess\"

# BootloadHID
SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"16c0\", ATTRS{idProduct}==\"05df\", TAG+=\"uaccess\"

# USBAspLoader
SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"16c0\", ATTRS{idProduct}==\"05dc\", TAG+=\"uaccess\"

# USBtinyISP
SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"1782\", ATTRS{idProduct}==\"0c9f\", TAG+=\"uaccess\"

# ModemManager should ignore the following devices
# Atmel SAM-BA (Massdrop)
SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"03eb\", ATTRS{idProduct}==\"6124\", TAG+=\"uaccess\", ENV{ID_MM_DEVICE_IGNORE}=\"1\"

# Caterina (Pro Micro)
## pid.codes shared PID
### Keyboardio Atreus 2 Bootloader
SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"1209\", ATTRS{idProduct}==\"2302\", TAG+=\"uaccess\", ENV{ID_MM_DEVICE_IGNORE}=\"1\"
## Spark Fun Electronics
### Pro Micro 3V3/8MHz
SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"1b4f\", ATTRS{idProduct}==\"9203\", TAG+=\"uaccess\", ENV{ID_MM_DEVICE_IGNORE}=\"1\"
### Pro Micro 5V/16MHz
SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"1b4f\", ATTRS{idProduct}==\"9205\", TAG+=\"uaccess\", ENV{ID_MM_DEVICE_IGNORE}=\"1\"
### LilyPad 3V3/8MHz (and some Pro Micro clones)
SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"1b4f\", ATTRS{idProduct}==\"9207\", TAG+=\"uaccess\", ENV{ID_MM_DEVICE_IGNORE}=\"1\"
## Pololu Electronics
### A-Star 32U4
SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"1ffb\", ATTRS{idProduct}==\"0101\", TAG+=\"uaccess\", ENV{ID_MM_DEVICE_IGNORE}=\"1\"
## Arduino SA
### Leonardo
SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"2341\", ATTRS{idProduct}==\"0036\", TAG+=\"uaccess\", ENV{ID_MM_DEVICE_IGNORE}=\"1\"
### Micro
SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"2341\", ATTRS{idProduct}==\"0037\", TAG+=\"uaccess\", ENV{ID_MM_DEVICE_IGNORE}=\"1\"
## Adafruit Industries LLC
### Feather 32U4
SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"239a\", ATTRS{idProduct}==\"000c\", TAG+=\"uaccess\", ENV{ID_MM_DEVICE_IGNORE}=\"1\"
### ItsyBitsy 32U4 3V3/8MHz
SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"239a\", ATTRS{idProduct}==\"000d\", TAG+=\"uaccess\", ENV{ID_MM_DEVICE_IGNORE}=\"1\"
### ItsyBitsy 32U4 5V/16MHz
SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"239a\", ATTRS{idProduct}==\"000e\", TAG+=\"uaccess\", ENV{ID_MM_DEVICE_IGNORE}=\"1\"
## dog hunter AG
### Leonardo
SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"2a03\", ATTRS{idProduct}==\"0036\", TAG+=\"uaccess\", ENV{ID_MM_DEVICE_IGNORE}=\"1\"
### Micro
SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"2a03\", ATTRS{idProduct}==\"0037\", TAG+=\"uaccess\", ENV{ID_MM_DEVICE_IGNORE}=\"1\"

# hid_listen
KERNEL==\"hidraw*\", MODE=\"0660\", GROUP=\"plugdev\", TAG+=\"uaccess\", TAG+=\"udev-acl\"

# hid bootloaders
## QMK HID
SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"03eb\", ATTRS{idProduct}==\"2067\", TAG+=\"uaccess\"
## PJRC's HalfKay
SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"16c0\", ATTRS{idProduct}==\"0478\", TAG+=\"uaccess\"

# APM32 DFU
SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"314b\", ATTRS{idProduct}==\"0106\", TAG+=\"uaccess\"

# GD32V DFU
SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"28e9\", ATTRS{idProduct}==\"0189\", TAG+=\"uaccess\"

# WB32 DFU
SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"342d\", ATTRS{idProduct}==\"dfa0\", TAG+=\"uaccess\"
")))

(define-public base-system-packages
  (append (map specification->package
               '( "nss-certs"
		  "sway"
		  "dbus-glib"
                  "hyprland"
                  "mesa"
                  "mesa-utils"
                  "android-udev-rules"
                  "adb"
                  "fastboot"
                  "vulkan-tools"
                  "vulkan-headers"
                  "libva"
                  "libva-utils"
                  "intel-vaapi-driver"
                  "libvdpau"
                  "libvdpau-va-gl"
                  "xf86-input-libinput"
		  "emacs-next-pgtk"))
          %base-packages))

(define-public base-system-services
   (append
    (list ;; To configure OpenSSH, pass an 'openssh-configuration'
     ;; record as a second argument to 'service' below.
     (service openssh-service-type)
     fontconfig-file-system-service
     (service sane-service-type)
     (service cups-service-type
              (cups-configuration
               (web-interface? #t)
               (extensions
                (list cups-filters))))

     (simple-service 'mtp udev-service-type (list libmtp))
     (udev-rules-service 'pipewire-add-udev-rules pipewire)
     (udev-rules-service 'brightnessctl-udev-rules brightnessctl)
     (udev-rules-service 'android android-udev-rules
                         #:groups '("adbusers"))
     (udev-rules-service 'qmk qmk-udev-rules)

     ;;(service seatd-service-type)
     (service nix-service-type)

     (service screen-locker-service-type
              (screen-locker-configuration
               (name "swaylock")
               (program (file-append 'swaylock-effects "/home/chris/.guix-home/profile/bin/swaylock"))
               (allow-empty-password? #f)
               (using-pam? #t)
               (using-setuid? #f)))

     (set-xorg-configuration
      (xorg-configuration (keyboard-layout (keyboard-layout "us"))
                          (drivers '("modesetting" "mesa"))))
              
     (service console-font-service-type
              (map (lambda (tty)
                     ;; Use a larger font for HIDPI screens
                     (cons tty (file-append
                                font-terminus
                                "/share/consolefonts/ter-132n")))
                   '("tty1" "tty2" "tty3" "tty4" "tty5" "tty6")))

     (service greetd-service-type
              (greetd-configuration
               (greeter-supplementary-groups
                (list "input" "video"))
               (terminals
                (list
                 (greetd-terminal-configuration
                  (terminal-vt "1")
                  (terminal-switch #t)
                  (default-session-command
                    (greetd-agreety-session
                     (command
                      (file-append dbus "/bin/dbus-run-session"))
                     (command-args (list "Hyprland")))))
                 (greetd-terminal-configuration (terminal-vt "2"))
                 (greetd-terminal-configuration (terminal-vt "3"))
                 (greetd-terminal-configuration (terminal-vt "4"))
                 (greetd-terminal-configuration (terminal-vt "5"))
                 (greetd-terminal-configuration (terminal-vt "6"))))))

     ;; NetworkManager and its applet.
     (service network-manager-service-type)
     (service wpa-supplicant-service-type) ;needed by NetworkManager
     (simple-service 'network-manager-applet
                     profile-service-type
                     (list network-manager-applet))
     (service modem-manager-service-type)
     (service usb-modeswitch-service-type)
     (service bluetooth-service-type
              (bluetooth-configuration
               (auto-enable? #t)))

     ;; The D-Bus clique.
     polkit-wheel-service
     (service avahi-service-type)
     (service udisks-service-type)
     (service upower-service-type)
     ;; (service accountsservice-service-type)
     (service cups-pk-helper-service-type)
     (service colord-service-type)
     (service geoclue-service-type)
     (service polkit-service-type)
     (service elogind-service-type)
     (service dbus-root-service-type)

     (service ntp-service-type)

     (service x11-socket-directory-service-type))

    (modify-services %base-services
                     (guix-service-type config => (guix-configuration
                                                   (inherit config)
                                                   (substitute-urls
                                                    (append (list "https://substitutes.nonguix.org" "http://172.16.1.7:8080")
                                                            %default-substitute-urls))
                                                   (authorized-keys
                                                    (append (list
                                                             (plain-file "nonguix.pub" "(public-key (ecc (curve Ed25519) (q #C1FD53E5D4CE971933EC50C9F307AE2171A2D3B52C804642A7A35F84F3A4EA98#)))")
                                                             (plain-file "kaladin.pub"  "(public-key (ecc (curve Ed25519) (q #7C5E5BEDFC0650E10AE70762F481021C0633C57376DFC7B1C3C4BE0115FD4264#)))"))
                                                            %default-authorized-guix-keys))
                                                   (discover? #t)))
                     ;; greetd-service-type provides "greetd" PAM service
                     (delete login-service-type)
                     (delete console-font-service-type)
                     ;; and can be used in place of mingetty-service-type
                     (delete mingetty-service-type)
                     (delete mingetty-service-type)
                     (delete mingetty-service-type)
                     (delete mingetty-service-type)
                     (delete mingetty-service-type)
                     (delete mingetty-service-type))))

(define-public base-operating-system
  (operating-system
   (kernel linux-xanmod)
   (initrd microcode-initrd)
   (firmware (list linux-firmware))
   (locale "en_US.utf8")
   (timezone "America/Chicago")
   (keyboard-layout (keyboard-layout "us"))
   (host-name "narnia")

   ;; Additional kernel modules
   (kernel-loadable-modules (list v4l2loopback-linux-module))

   ;; The list of user accounts ('root' is implicit).
   (users (cons* (user-account
                  (name "chris")
                  (comment "Chris")
                  (group "users")
                  (home-directory "/home/chris")
                  (supplementary-groups '("wheel"
                                          "netdev"
                                          "tty"
                                          "input"
                                          "lp"
                                          "audio"
                                          "video"
                                          "adbusers")))
                 %base-user-accounts))

   (sudoers-file etc-sudoers-config)
   (packages base-system-packages)
   (services base-system-services)

   (bootloader (bootloader-configuration
                (bootloader grub-efi-bootloader)
                (targets (list "/boot/efi"))
                (keyboard-layout keyboard-layout)))

   ;; Guix doesn't like it when there isn't a file-systems
   ;; entry, so add one that is meant to be overridden
   (file-systems (cons*
                  (file-system
                   (mount-point "/tmp")
                   (device "none")
                   (type "tmpfs")
                   (check? #f))
                  %base-file-systems))))
