(define-module (glicid services networking)
  #:use-module (gnu packages bash)
  #:use-module (gnu packages networking)
  #:use-module (gnu services)
  #:use-module (gnu services shepherd)
  #:use-module (gnu system shadow)
  #:use-module (guix)
  #:use-module (guix records)
  #:use-module (ice-9 match)
  #: export (
    squid-configuration
    squid-configuration?
    squid-shepherd-service
    squid-service-type
  )
)

(define-record-type* <squid-configuration>
  squid-configuration make-squid-configuration
  squid-configuration?
  (squid squid-configuration-squid
    (default squid)
  )
  (port squid-configuration-port
    (default 3128)
  )
  (loglevel squid-configuration-loglevel
    (default 1)
  )
  (pid-file squid-configuration-pid-file
    (default "/var/run/squid/squid.pid")
  )
  (config-file squid-configuration-config-file
    (default (file-append squid "/etc/squid.conf"))
  )
  (log-file squid-configuration-log-file
    (default "/var/log/squid/squid.log")
  )
)

(define squid-shepherd-service
  (match-lambda
    (($ <squid-configuration> squid port loglevel pid-file config-file log-file)
      (list
        (shepherd-service
          (provision '(squid) )
          (documentation "Run squid.")
          (requirement '(user-processes))
          (respawn? #t)
          (start #~(make-forkexec-constructor
            (list
              #$(file-append squid "/sbin/squid")
              "-f" #$config-file
            )
            #:pid-file #$pid-file 
            #:log-file #$log-file
            #:user (passwd:uid (getpwnam "squid"))
            #:group (passwd:gid (getpwnam "squid"))
            #:resource-limits '((nofile 16384 16384))
          ))
          (stop #~(make-kill-destructor))
        )
      )
    )
  )
)


(define %squid-activation
  (with-imported-modules '((guix build utils))
    #~(begin
        (use-modules (guix build utils))
        (define (touch file-name)
          (call-with-output-file file-name (const #t))
        )
        (mkdir-p "/var/run/squid")
        (mkdir-p "/var/log/squid")
        (mkdir-p "/var/cache/squid")
        (mkdir-p "/var/spool/squid")
        (touch "/var/log/squid/squid.log")
        (touch "/var/log/squid/squid_access.log")
        (touch "/var/log/squid/squid_cache.log")
        (touch "/var/log/squid/squid_cache_store.log")
        (chown "/var/run/squid" (passwd:uid (getpwnam "squid")) (passwd:gid (getpwnam "squid")))
        (chown "/var/cache/squid" (passwd:uid (getpwnam "squid")) (passwd:gid (getpwnam "squid")))
        (chown "/var/log/squid" (passwd:uid (getpwnam "squid")) (passwd:gid (getpwnam "squid")))
        (chown "/var/spool/squid" (passwd:uid (getpwnam "squid")) (passwd:gid (getpwnam "squid")))
        (chown "/var/log/squid/squid.log" (passwd:uid (getpwnam "squid")) (passwd:gid (getpwnam "squid")))
        (chown "/var/log/squid/squid_access.log" (passwd:uid (getpwnam "squid")) (passwd:gid (getpwnam "squid")))
        (chown "/var/log/squid/squid_cache.log" (passwd:uid (getpwnam "squid")) (passwd:gid (getpwnam "squid")))
        (chown "/var/log/squid/squid_cache_store.log" (passwd:uid (getpwnam "squid")) (passwd:gid (getpwnam "squid")))
        #t
    )
  )
)

(define %squid-accounts
  (list
    (user-group (name "squid") (system? #t))
    (user-account
      (name "squid")
      (group "squid")
      (system? #t)
      (comment "Squid server user")
      (home-directory "/var/spool/squid")
      (shell (file-append bash "/bin/bash"))
    )
  )
)

(define squid-service-type
  (service-type (name 'squid)
    (extensions 
      (list
        (service-extension shepherd-root-service-type squid-shepherd-service)
        (service-extension activation-service-type (const %squid-activation))
        (service-extension account-service-type (const %squid-accounts))
      )
    )
    (description "Run @uref{http://www.squid-cache.org/, squid} community developped Squid software.")
  )
)
