... This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
... If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.

(.using
 [library
  [lux (.except)
   ["[0]" ffi (.only import)]
   [abstract
    ["[0]" monad]]
   [concurrency
    ["[0]" future (.only Future)]]
   [control
    ["[0]" pipe]
    ["[0]" io (.only IO)]]
   [error
    ["[0]" try (.only Try)]]
   [function
    [predicate (.only Predicate)]]
   [data
    [binary (.only Binary)]
    ["[0]" text (.only)
     ["%" \\injection]
     [encoding
      ["[0]" utf8]]]
    [collection
     ["[0]" list]
     ["[0]" set]
     ["[0]" dictionary]]
    [format
     ["[0]" tar]
     ["[0]" xml]]]
   [macro
    ["[0]" template]]
   [compiler
    [meta
     ["[0]" export]
     ["[0]" archive]
     ["[0]" context]
     ["[0]" packager
      ["[1]" jvm]]]]
   [world
    ["[0]" environment
     [/ (.only Environment)]
     ["[1]" \\projection]]
    [console (.only Console)]
    ["[0]" shell (.only Shell)]
    ["[0]" file]]]]
 ["[0]" //
  ["[1][0]" snapshot]
  ["/[1]" //
   ["[1][0]" install]
   ["/[1]" //
    [command (.only Command)]
    ["/" profile]
    ["[1][0]" action]
    ["[1][0]" pom]
    ["[1][0]" package]
    ["[1][0]" hash]
    ["[1][0]" dependency
     ["[1]/[0]" deployment]
     ["[1]/[0]" status]]
    ["[1][0]" repository (.only Repository)
     ["[1]/[0]" origin]
     ["[1]/[0]" local]]
    ["[1][0]" artifact (.only Artifact)
     ["[1]/[0]" type]
     ["[1]/[0]" extension (.only Extension)]]]]])

(import java/lang/String
        "[1]::[0]"
        (toLowerCase [] java/lang/String))

(import java/lang/System
        "[1]::[0]"
        ("static" getProperty [java/lang/String] "io" "try" java/lang/String))

(the windows?
  (IO (Try Bit))
  (by (try.with io.monad) each
      (|>> (java/lang/String::toLowerCase []) ffi.of_string (text.starts_with? "windows"))
      (java/lang/System::getProperty [(ffi.as_string "os.name")])))

(the dummy_jar
  Binary
  (|> (packager.package (context.jvm "")
                        (dictionary.empty text.hash)
                        archive.empty
                        {.#None})
      try.trusted
      (pipe.when
        {.#Left it}
        it
        
        {.#Right _}
        (undefined))))

(template.with [<name> <extension>]
  [(the <name>
     (-> Text Text)
     (text.suffix <extension>))]

  [[asc ".asc"]
   [pom ////artifact/extension.pom]
   [tar ////artifact/extension.lux_library]
   [jar ////artifact/extension.jvm_library]
   [sha1 ////artifact/extension.sha1]
   [md5 ////artifact/extension.md5]])

(template.with [<name> <suffix>]
  [(the <name>
     (-> Text Text)
     (|>> (text.suffix <suffix>) ..jar))]

  [[javadoc "-javadoc"]
   [sources "-sources"]])

(the .public release?
  (Predicate Artifact)
  (|>> //snapshot.snapshot? not))

(the (install_dummies! environment local fs artifact)
  (-> (Environment Future) (Repository Future) (file.System Future) Artifact (Future (Try Any)))
  (monad.let (try.with future.monad)
    [.let [$artifact (////artifact.uri (its ////artifact.#version artifact) artifact)]
     _ (by local upload (..jar $artifact) ..dummy_jar)
     _ (by local upload (..javadoc $artifact) ..dummy_jar)
     _ (by local upload (..sources $artifact) ..dummy_jar)]
    (pure [])))

(the (signed it)
  (-> Text [Text Text])
  [it (..asc it)])

(the (release_unsigned_artifact! local remote uri)
  (-> (Repository Future) (Repository Future) Text (Future (Try Binary)))
  (monad.let [! ////action.monad]
    [it (by local download uri)
     _ (by remote upload uri it)]
    (pure it)))

(the (release_signed_artifact! local remote [artifact signature])
  (-> (Repository Future) (Repository Future) [Text Text] (Future (Try Any)))
  (monad.let [! ////action.monad]
    [it (..release_unsigned_artifact! local remote artifact)
     _ (|> it
           ////hash.md5
           (by ////hash.md5_format as)
           (by utf8.binary as)
           (by remote upload (..md5 artifact)))
     _ (|> it
           ////hash.sha1
           (by ////hash.sha1_format as)
           (by utf8.binary as)
           (by remote upload (..sha1 artifact)))
     _ (..release_unsigned_artifact! local remote signature)]
    (pure [])))

(the .public (do! environment shell console local remote fs artifact profile)
  (-> (Environment Future) (Shell Future) (Console Future) (Repository Future) (Repository Future) (file.System Future) Artifact (Command Any))
  (monad.let [! ////action.monad]
    [_ (///install.do! console fs local profile)
     _ (install_dummies! environment local fs artifact)
     .let [@root (////repository/local.root environment fs)
           $bundle (////artifact.bundle (its ////artifact.#version artifact) artifact)
           / (by fs delimiter)
           @local (text @root / $bundle)]
     windows? (future.soon ..windows?)
     process (is (Future (Try (shell.Process Future)))
                 (by shell execute [environment.empty @local
                                    (if windows?
                                        ["cmd" (list "/c" "for %file in (.\*) do gpg.exe -ab %file")]
                                        ["sh" (list "-c" "for file in *.*; do gpg -ab $file; done")])]))
     exit (is (Future (Try shell.Exit))
              (by process await []))
     .let [$artifact (////artifact.uri (its ////artifact.#version artifact) artifact)]
     _ (list.each' ! (release_signed_artifact! local remote)
                   (list (..signed (..pom $artifact))
                         (..signed (..tar $artifact))
                         (..signed (..jar $artifact))
                         (..signed (..javadoc $artifact))
                         (..signed (..sources $artifact))))]
    (pure [])))
