#!/usr/local/bin/clisp
;
; Notify Daemon (login as grid and type "./notify.lisp &" to start)
; Simple Grid Protocol 1.04 - Copyright (c) Brendan Kosowski 2004, 2005, 2015
;
(defvar c)
(defvar n)
(defvar fr)
(defvar subst)
(defvar slist)
(defvar slista) ; list (array) of multiple slist
(defvar idle)
(defvar token)
(defvar my_ip)
(defvar track_ip)
(defvar cpu_freq)
(defvar cprev)
(defvar lin)
(defvar stm)
(defvar acr)
(defvar flags)
(defvar flist) ; now a 2 dimension list (array)
; using vmstat instead of top for CPU idle%
;(defvar topcommand "top -b -n2 -d30.00 -p0 > /home/grid/top.dat")
(defvar topcommand "vmstat 30 2 > /home/grid/top.dat")

; returning a 2 dimension list (array) ie. lines by words
(defun file-to-list (file)
	(setq fr (open file :direction :input))
	(setq c #\space)
	(setq slist NIL)
	(setq slista NIL) ; mod
	(setq subst "")
	(loop
		(setq cprev c)
		(setq c (read-char fr nil))
		(unless c (return))
		(if (or (char= c #\space) (char= c #\newline))
			(when (and (char/= cprev #\space) (char/= cprev #\newline))
				(push subst slist)
				(setq subst "")
			)
			(setq subst (concatenate 'string subst (string c)))
		)
		; push to 2 dimension list (array) for each newline
		(when (char= c #\newline)
			(push (reverse slist) slista)
			(setq slist NIL)
		)
	)
	(close fr)
	(if (string/= subst "") (push subst slist))
	; push to 2 dimension list (array) if EOF (no prior newline)
	;(reverse slist)
	(if (char/= cprev #\newline) (push (reverse slist) slista))
	(setq slist NIL)
	; reverse 2 dimension list (array)
	(reverse slista)
)

(setq fr (open "/home/grid/token.dat" :direction :input))
(setq token (read-line fr))
(close fr)

(setq fr (open "/home/grid/my_ip.dat" :direction :input))
(setq my_ip (read-line fr))
(close fr)

(setq fr (open "/home/grid/track_ip.dat" :direction :input))
(setq track_ip (read-line fr))
(close fr)

(setq fr (open "/home/grid/cpu_freq.dat" :direction :input))
(setq cpu_freq (read-from-string (read-line fr)))
(close fr)

(setq fr (open "/home/grid/flags.dat" :direction :input))
(setq flags (read fr))
(close fr)

(loop
	(ext:shell topcommand)
	(setq flist (file-to-list "top.dat"))
	; using 2 dimension list (array)
	;(setq n (position "idle" flist :from-end t :test #'string=))
	;(setq idle (read-from-string (string-right-trim "%" (nth (- n 1) flist))))
	(setq n (position "id" (nth 1 flist) :from-end t :test #'string=))
	(setq idle (read-from-string (nth n (nth 3 flist))))

	(setq acr (* cpu_freq (/ idle 100)))

	(setq stm (socket:socket-connect 17667 track_ip))
	(loop
		(setq lin (read-line stm))
		(when (search "Grid" lin) (return))
	)

	(setq lin (read-line stm))
	(when (string= lin "token?")
		(format stm "~a~%" token)
	)

	(setq lin (read-line stm))
	(when (string= lin "what?")
		(format stm "join~%")
	)

	(setq lin (read-line stm))
	(when (string= lin "ip?")
		(format stm "~a~%" my_ip)
	)

	(setq lin (read-line stm))
	(when (string= lin "acr?")
		(format stm "~a~%" acr)
	)

	(setq lin (read-line stm))
	(when (string= lin "flags?")
		(prin1 flags stm)
		(format stm "~%")
	)

	(setq lin (read-line stm))
	(when (string= lin "what?")
		(format stm "bye~%")
	)

	(close stm)
)
