 ;
 ; Copyright (C) 2011,2012 Carlo Sciolla
+;               2014      Peter Monks rewritten around fn-generating macros
 ;
 ; Licensed under the Apache License, Version 2.0 (the "License");
 ; you may not use this file except in compliance with the License.

  (:import [org.alfresco.repo.policy JavaBehaviour
                                     Behaviour$NotificationFrequency]))

;; no static String to use here, unfortunately
(defn policy-component
  []
  (c/get-bean "policyComponent"))

(comment
(defn- bind-class-behaviour!
  [policy-qname binding-type-qname behaviour]
  (.bindClassBehaviour (policy-component)
                       policy-qname
                       (m/qname binding-type-qname)
                       behaviour)
  nil)
)

(def ^:private policies
  [
    ['on-add-aspect!  org.alfresco.repo.node.NodeServicePolicies$OnAddAspectPolicy  'onAddAspect  '[node qname]]
    ['on-create-node! org.alfresco.repo.node.NodeServicePolicies$OnCreateNodePolicy 'onCreateNode '[child-assoc-ref]]
  ])

(defmacro ^:private gen-behaviour-registration-fn
  [fn-name policy-if policy-method params]
;  `(def ~fn-name
  `(defn ~fn-name
     ~(str "Registers the function f as a handler for behaviour " policy-if
           ", for the given qname. f must accept " (count params)
           " parameters: " (clojure.string/join ", " params)
           "\nNote: Handlers only fire on transaction commit.")
;     (fn [~'qname ~'f]
     [~'qname ~'f]
     (let [p# (reify ~policy-if
                (~policy-method [~'this ~@params]

                            ~(symbol (str policy-if "/QNAME"))
                            (m/qname ~'qname)
                            b#)
       nil)))

(defn- third
  "The third item in the given collection."
  [col]
  (first (next (next col))))

(defn- fourth
  "The fourth item in the given collection."
  [col]
  (first (next (next (next col)))))

(def ^:private policies
  "A list of all of the Alfresco policies supported by lambdalf.  This list is used by the macro below to
  generate the various registration methods and Alfresco Java API interop boilerplate."
  [
    ;clojure-fn-name        alfresco-policy-class                                                policy-method       policy-method-parameters
    ['on-create-node!       'org.alfresco.repo.node.NodeServicePolicies$OnCreateNodePolicy       'onCreateNode       '[child-assoc-ref]]
    ['on-update-node!       'org.alfresco.repo.node.NodeServicePolicies$OnUpdateNodePolicy       'onUpdateNode       '[node]]
    ['on-move-node!         'org.alfresco.repo.node.NodeServicePolicies$OnMoveNodePolicy         'onMoveNode         '[old-child-assoc-ref new-child-assoc-ref]]
    ['on-update-properties! 'org.alfresco.repo.node.NodeServicePolicies$OnUpdatePropertiesPolicy 'onUpdateProperties '[node before-props after-props]]
    ['on-delete-node!       'org.alfresco.repo.node.NodeServicePolicies$OnDeleteNodePolicy       'onDeleteNode       '[child-assoc-ref is-node-archived?]]
    ['on-restore-node!      'org.alfresco.repo.node.NodeServicePolicies$OnRestoreNodePolicy      'onRestoreNode      '[child-assoc-ref]]

    ['on-add-aspect!        'org.alfresco.repo.node.NodeServicePolicies$OnAddAspectPolicy        'onAddAspect        '[node aspect-qname]]
    ['on-remove-aspect!     'org.alfresco.repo.node.NodeServicePolicies$OnRemoveAspectPolicy     'onRemoveAspect     '[node aspect-qname]]
  ])

(defmacro ^:private gen-policy-registration-fns
  "Generates all policy registration fns defined in the 'policies' vector."
  []
  `(do ~@(for [policy policies]
           `(gen-policy-registration-fn ~(first  policy)
                                        ~(second policy)
                                        ~(third  policy)
                                        ~(fourth policy)))))

(gen-policy-registration-fns)
