(use-modules
  ((guix licenses) #:prefix license:)
  ((nongnu packages linux) #:prefix ng.linux:)
  ((nongnu system linux-initrd) #:prefix ng.initrd:)
  ((nonguix licenses) #:prefix ng.license:)
  ((org euandre packages) #:prefix pkg:)
  ((org euandre queue) #:prefix q:)
  ((hereguile) #:prefix hereguile:)
  (gnu)
  (gnu system locale)
  (guix build-system gnu)
  (guix download)
  (guix packages))
(use-package-modules
  cups
  cpio
  image
  package-management
  wm)
(use-service-modules
  cups
  desktop
  docker
  mail
  nix
  pm
  security-token
  sound
  ssh
  sysctl
  virtualization
  vpn
  xorg)
(hereguile:enable-syntax)


(define host-name "novinho")
(define wg0-ipaddr "10.0.0.5")
(define wg1-ipaddr "10.0.1.5")


;; Implement wireless printing before sending upstream
(define-public epson-L365
  (package
    (name "epson-L365")
    (version "1.0.0")
    (source
      (local-file
       (string-append
        (dirname (current-filename))
        "/epson-inkjet-printer-201401w-"
        version
        "-1lsb3.2.src.rpm")))
    (build-system gnu-build-system)
    (arguments
      (list
       #:phases
       #~(modify-phases %standard-phases
           (replace 'unpack
             (lambda* (#:key outputs #:allow-other-keys)
               (mkdir "source")
               (chdir "source")
               (system (string-append "rpm2cpio " #$source " | cpio -idv"))
               (invoke "tar" "-xvf" (string-append "epson-inkjet-printer-201401w-" #$version ".tar.gz"))
               (invoke "tar" "-xvf" (string-append "epson-inkjet-printer-filter-"  #$version ".tar.gz"))
               (substitute* (find-files (string-append "epson-inkjet-printer-201401w-" #$version "/ppds/"))
                 (("/opt/epson-inkjet-printer-201401w/cups/lib")
                  (string-append (assoc-ref outputs "out")
                                 "/lib/cups")))
               (chdir (string-append "epson-inkjet-printer-filter-" #$version))))
           (add-after 'install 'install-extra-files
             (lambda* (#:key outputs #:allow-other-keys)
               (let* ((out (assoc-ref outputs "out"))
                      (model-dir (string-append out "/share/cups/model/epson-inkjet-printer-201401w")))
                 (chdir (string-append "../epson-inkjet-printer-201401w-" #$version))
                 (mkdir-p model-dir)
                 (invoke "cp" "-a" "ppds" model-dir)
                 (invoke "cp" "-a" "lib64" "resource" "watermark" out)))))))
    (native-inputs
      (list
       cpio
       cups-minimal
       libjpeg-turbo
       rpm))
    (synopsis
     "Epson printer driver (L456, L455, L366, L365, L362, L360, L312, L310, L222, L220, L132, L130)")
    (description
     "This software is a filter program used with the Common UNIX Printing
System (CUPS) under Linux.  It supplies high quality printing with
Seiko Epson Color Ink Jet Printers.")
    (home-page "https://www.openprinting.org/driver/epson-201401w")
    (license                  ;; SEIKO EPSON CORPORATION SOFTWARE LICENSE AGREEMENT
      (list (ng.license:nonfree "https://epson.com/SoftwareLicenseAgreement")
            license:lgpl2.1))))


(define current-architecture
  (car
   (string-split %host-type
                 #\-)))

(define desired-architectures
  '("aarch64"
    "arm"
    "armeb"
    "i386"
    "m68k"
    "mips"
    "mips64"
    "mips64el"
    "mipsel"
    "mipsn32"
    "mipsn32el"
    "ppc"
    "ppc64"
    "ppc64le"
    "riscv32"
    "riscv64"
    "x86_64"))

(define platforms
  (filter (lambda (name)
            (not (equal? name current-architecture)))
          desired-architectures))


(operating-system
  (kernel ng.linux:linux)
  (initrd ng.initrd:microcode-initrd)
  (firmware (list ng.linux:linux-firmware))
  (locale "fr_FR.UTF-8")
  (locale-definitions
    (append
     (list
      (locale-definition
        (name   "pt_BR.UTF-8")
        (source "pt_BR")))
     %default-locale-definitions))
  (timezone "America/Sao_Paulo")
  (keyboard-layout
    (keyboard-layout "br" #:options '("caps:swapescape" "esperanto:qwerty")))
  (host-name host-name)
  (users
    (append
     (list
      (user-account
        (name "teste")
        (comment "teste")
        (group "users")
        (supplementary-groups '()))
      (user-account
        (name "andreh")
        (comment "EuAndreh,,,,eu@euandre.org")
        (group "users")
        (supplementary-groups '("netdev" "audio" "video" "wheel" "peer" "kvm" "docker" "dialout"))))
     %base-user-accounts))
  (packages
    (append
     (map (compose list specification->package+output symbol->string)
          '(ghc
            ghc-xmonad-contrib
            rsync
            xmobar
            xmonad))
     (list)
     %base-packages))
  (services
    (append
     (list
      (service gpm-service-type)
      (service bluetooth-service-type)
      (service tlp-service-type)
      (service thermald-service-type)
      (service pcscd-service-type)
      (service docker-service-type)
      (service containerd-service-type)
      (service libvirt-service-type)
      (service virtlog-service-type)
      (service nix-service-type)
      (service pkg:transactor-service-type)
      (simple-service 'add-wireguard-aliases hosts-service-type
        (list
         (host "10.0.0.0" "toph")
         (host "10.0.1.0" "asami")))
      (service q:local-postfix-service-type
        (q:postfix-configuration
          (main.cf-extra #"-
            smtp_sender_dependent_authentication = yes
            sender_dependent_relayhost_maps = hash:/var/lib/private/postfix/relayhosts-maps
            smtp_sasl_password_maps = hash:/var/lib/private/postfix/sasl-password
            smtp_sasl_auth_enable = yes
            smtp_sasl_security_options = noanonymous
            smtp_sasl_mechanism_filter = login, plain
            smtp_use_tls = yes
            smtp_tls_security_level = encrypt
            smtp_tls_note_starttls_offer = yes
            message_size_limit = 102400000
            mailbox_size_limit = 5120000000
            "#)))
      (service mail-aliases-service-type
        '(("root"   "andreh")
          ("andreh" "eu@euandre.org")))
      (service wireguard-service-type
        (wireguard-configuration
          (interface   "wg0")
          (private-key "/etc/wireguard/toph.key")
          (addresses
            (list
             (string-append wg0-ipaddr "/32")))
          (peers
            (list
             (wireguard-peer
               (name "toph")
               (endpoint "euandre.org:51820")
               (public-key "8jJgTIWrs7HNWlJXOwl8A0DKqIiAGa4hhh/hcXm4EUs=")
               (allowed-ips '("10.0.0.0/32"))
               (keep-alive 25))))))
      (service wireguard-service-type
        (wireguard-configuration
          (interface   "wg1")
          (private-key "/etc/wireguard/asami.key")
          (addresses
            (list
             (string-append wg1-ipaddr "/32")))
          (peers
            (list
             (wireguard-peer
               (name "asami")
               (endpoint "papo.im:51820")
               (public-key "xWeNyN4GmdsoGZKswuNVj6z7WHqlE5WwUGs3S1quBis=")
               (allowed-ips '("10.0.1.0/32"))
               (keep-alive 25))))))
      (service qemu-binfmt-service-type
        (qemu-binfmt-configuration
          (platforms
            (apply lookup-qemu-platforms platforms))))
      (service cups-service-type
        (cups-configuration
          (web-interface? #t)
          (extensions
            (list cups-filters epson-L365))))
      (service openssh-service-type
        (openssh-configuration
          (password-authentication? #f)
          (extra-content #"-
            ClientAliveInterval 30
            ClientAliveCountMax 20
            MaxSessions 20
            "#)))
      (set-xorg-configuration
        (xorg-configuration
          (keyboard-layout keyboard-layout)
          (extra-config
            (list
             #"-
               Section "InputClass"
                   Identifier "touchpad"
                   Driver "libinput"
                   MatchIsTouchpad "on"
                   Option "Tapping" "on"
               EndSection
               "#)))))
     (modify-services %desktop-services
       (sysctl-service-type config =>
         (sysctl-configuration
           (inherit config)
           (settings
             (append
              (sysctl-configuration-settings config)
              '(("vm/swappiness" . "200") ;; chorume: this should be calculated based on (RAM size)/(swap size) ratio
                ("kernel/core_pattern" . "/var/crash/core-%t-%e-%p-%s-%u-%g"))))))
       (pulseaudio-service-type config =>
         (pulseaudio-configuration
           (inherit config)
           (extra-script-files
             (list
              (plain-file
               "noise-cancelling.pa"
               "load-module module-echo-cancel")))))
       (guix-service-type config =>
         (guix-configuration
           (inherit config)
           (substitute-urls
             (append
              '("https://substitutes.nonguix.org")
              %default-substitute-urls))
           (authorized-keys
             (append
              (list
               (plain-file
                "non-guix.pub"
                #"-
                  (public-key
                    (ecc
                      (curve Ed25519)
                      (q #C1FD53E5D4CE971933EC50C9F307AE2171A2D3B52C804642A7A35F84F3A4EA98#)))
                  "#))
              %default-authorized-guix-keys)))))))
  (name-service-switch %mdns-host-lookup-nss)
  (bootloader
    (bootloader-configuration
      (bootloader grub-efi-bootloader)
      (targets '("/boot/efi"))
      (keyboard-layout keyboard-layout)))
  (mapped-devices
    (list
     (mapped-device
       ;; AKA /dev/nvme0n1p2
       (source (uuid "99777544-e6ed-46d7-b154-bd44124a812b"))
       (target "cryptroot")
       (type luks-device-mapping))))
  (file-systems
    (append
     (list
      (file-system
        (mount-point "/boot/efi")
        ;; AKA /dev/nvme0n1p1
        (device (uuid "AE8A-8926" 'fat32))
        (type "vfat"))
      (file-system
        (mount-point "/")
        (device "/dev/mapper/cryptroot")
        (type "btrfs")
        (dependencies mapped-devices)))
     %base-file-systems))
  (swap-devices
    (list
     (swap-space
       ;; # rm -f            /swapfile
       ;; # truncate -s 0    /swapfile
       ;; # chattr +C        /swapfile
       ;; # fallocate -l 32G /swapfile
       ;; # chmod 600        /swapfile
       ;; # mkswap           /swapfile
       ;; # swapon           /swapfile
       (target "/swapfile")
       (dependencies
         (filter (file-system-mount-point-predicate "/")
                 file-systems))))))
