# Sources for this configuration:
# - https://nixos.wiki/wiki/Printing

{ pkgs, lib, ... }:

let
  # https://github.com/philpem/printer-driver-ptouch
  printer-driver-ptouch = pkgs.stdenv.mkDerivation rec {
    pname = "printer-driver-ptouch";
    version = "1.7";

    src = pkgs.fetchgit {
      url = "https://github.com/philpem/printer-driver-ptouch";
      rev = "v${version}";
      hash = "sha256-3ZotSHn7lERp53hAzx47Ct/k565rEoensCcltwX/Xls=";
    };

    nativeBuildInputs = [
      pkgs.autoreconfHook
      pkgs.perl
    ];

    buildInputs = [
      pkgs.cups
      pkgs.libpng
      pkgs.perlPackages.XMLLibXML
      pkgs.foomatic-db-engine
    ];

    patches = [
      # Add this patch to have the package actually build sucessfully.
      # https://github.com/philpem/printer-driver-ptouch/pull/35
      (pkgs.fetchpatch {
        name = "fix-brother-ql-600.xml.patch";
        url = "https://patch-diff.githubusercontent.com/raw/philpem/printer-driver-ptouch/pull/35.patch";
        hash = "sha256-y5bHKFeRXx8Wdl1++l4QNGgiY41LY5uzrRdOlaZyF9I=";
      })
    ];

    # Used the following as a reference on how to generate the ppd files.
    # https://salsa.debian.org/printing-team/ptouch-driver/-/blob/4ba5d2c490ea1230374aa4b0bf711bf77f1ab0c7/debian/rules#L34
    postInstall = ''
      mkdir -p $out/share/cups
      FOOMATICDB=$out/share/foomatic ${pkgs.foomatic-db-engine}/bin/foomatic-compiledb -t ppd -d $out/share/cups/model
      rm -r $out/share/foomatic
    '';

    postPatch = ''
      patchShebangs --build foomaticalize
    '';
  };
  forcecommand-lpr-wrapper = pkgs.python3Packages.buildPythonApplication {
    name = "forcecommand-lpr-wrapper";
    src = ./forcecommand-lpr-wrapper;

    propagatedBuildInputs = [
      pkgs.cups
    ];
  };
in
{
  services.printing = {
    enable = true;
    drivers = [ printer-driver-ptouch ];
    stateless = true;
  };

  hardware.printers = {
    ensurePrinters = [
      {
        name = "Brother-QL-500";
        location = "Z9";
        deviceUri = "usb://Brother/QL-500?serial=J8Z249208";
        model = "Brother-QL-500-ptouch-ql.ppd";
        ppdOptions = {
          PageSize = "Custom.62x35mm";
        };
      }
    ];
    ensureDefaultPrinter = "Brother-QL-500";
  };

  users.users.print = {
    isNormalUser = true;
    description = "User for printing via SSH.";
    password = "";
  };

  # PasswordAuthentication being set to false just puts "auth required
  # pam_deny.so # deny (order 12400)" for pam.d/sshd, so enable
  # PasswordAuthentication to have it not do that.
  services.openssh.settings.PasswordAuthentication = lib.mkForce true;
  security.pam.services.sshd.allowNullPassword = true;
  services.openssh.extraConfig = ''
    Match User print
      PubkeyAuthentication no
      AuthenticationMethods none
      PermitEmptyPasswords yes
      ForceCommand ${forcecommand-lpr-wrapper}/bin/forcecommand-lpr-wrapper.py 
    Match User *
  '';
}