; Written by notostraca (tommy dot ettinger at gmail)
; Licensed under the EPL
(ns lazybot.plugins.nest
  (:use [lazybot registry info]
        [clojure.string :only [join trim split]]
        [clojure.pprint :only [pprint]]
        [clojail.core :only [thunk-timeout]]
        [overtone.at-at]
        )
  (:import java.io.PrintWriter
        java.util.concurrent.TimeoutException
  	  java.io.StringWriter))

(def my-pool (mk-pool))

(defplugin
  (:cmd
   "Calls two nested commands."
   #{"`" "!" "nest"} 
   (fn [{:keys [com bot nick args channel] :as com-m}]
       (with-open [sw (StringWriter.)]
   	   (let [
                   get-inner #(re-find #"\[\s*(\S+)\s+([^\]]+)\]" (join " " (rest %)))]
                   
     (if (and (seq args) 
     	       (find-command (:modules @bot) (first args))
     	       (seq (get-inner args))
     	       (find-command (:modules @bot) (nth (get-inner args) 1)))
       (do
       	 (let [inside-args (nth (get-inner args) 2)
       	 	 sout (get-in @com [:connection :sockout])
            ]
       	  (dosync (alter com assoc-in
                     [:connection :sockout] (PrintWriter. sw))
                  (alter com assoc :args (split inside-args #"\s"))
                  (alter com assoc :raw-args inside-args)
                  )
     (try
         	 ((:fn (find-command (:modules @bot) (nth (get-inner args) 1))) (assoc com-m :args (split inside-args #"\s")))
         (after 1000 (fn [] (do
         		 (.flush (get-in @com [:connection :sockout]))
         (.close (get-in @com [:connection :sockout]))
         
         (let [new-args (.toString sw )]
         
         (dosync (alter com assoc-in
                     [:connection :sockout] sout)
                  (alter com assoc :args (split (last (split new-args #" \:" 2)) #"\s"))
                  (alter com assoc :raw-args (join " " (split (last (split new-args #" \:" 2)) #"\s"))))
           ((:fn (find-command (:modules @bot) (first args))) (assoc com-m :args (split (last (split new-args #" \:" 2)) #"\s")))
         ))) my-pool)
     (catch TimeoutException e (send-message com-m "Nested execution timeout.") ))))))))))
