 (extend-protocol IJavaScript
   
   String
+  (-foreign? [this] false)
   (-url [this] nil)
   (-provides [this] (:provides (parse-js-ns (string/split-lines this))))
   (-requires [this] (:requires (parse-js-ns (string/split-lines this))))
   (-source [this] this)
   
   clojure.lang.IPersistentMap
+  (-foreign? [this] (:foreign this))
   (-url [this] (or (:url this)
                    (to-url (:file this))))
   (-provides [this] (map name (:provides this)))


(defmethod javascript-name JavaScriptFile [js] (javascript-name (-url js)))

(defmethod js-source-file JavaScriptFile [_ js]
  (when-let [url (-url js)]
    (js-source-file (javascript-name url) (io/input-stream url))))

(defn optimize
  "Use the Closure Compiler to optimize one or more JavaScript files."


(def load-library (memoize load-library*))

(defn library-dependencies [{:keys [libs foreign-libs]}]
  (concat
   (mapcat load-library libs)
   (map load-foreign-library foreign-libs)))

(comment
  ;; load one library
  (load-library* "closure/library/third_party/closure")
  ;; load all library dependencies
  (library-dependencies {:libs ["closure/library/third_party/closure"]})
  (library-dependencies {:foreign-libs [{:file "http://example.com/remote.js"
                                          :provides ["my.example"]}]})
  (library-dependencies {:foreign-libs [{:file "local/file.js"
                                            :provides ["my.example"]}]})
  (library-dependencies {:foreign-libs [{:file "cljs/nodejs_externs.js"
                                          :provides ["my.example"]}]}))

(defn goog-dependencies*
  "Create an index of Google dependencies by namespace and file name."
