(.module:
  [lux (#- Definition)
   [data
    ["." maybe ("#\." functor)]
    ["." text
     ["%" format (#+ format)]]
    [collection
     ["." list ("#\." functor monoid)]]]]
  [//
   ["." license (#+ Identification
                    Termination
                    Liability
                    Distribution
                    Commercial
                    Extension
                    Entity Black-List
                    URL Attribution
                    License)
    ["." copyright]
    ["." definition (#+ Definition)]
    ["." grant]
    ["." limitation]
    ["." assurance]
    ["." liability]
    ["." distribution]
    ["." commercial]
    ["." extension]
    ["." submission]
    ["." miscellaneous]
    ["." black-list]
    ["." notice]
    ["_" term]
    ["." addendum]]
   ["$" document]])

(def: #export (definition value)
  (-> Definition Text)
  (format ($.quote (get@ #definition.term value)) ": " (get@ #definition.meaning value)))

(def: #export (identification value)
  (-> Identification Text)
  (format (get@ #license.name value) text.new-line
          (get@ #license.version value)))

(def: #export (grant termination)
  (-> Termination Text)
  (`` (format (~~ (template [<title> <content>]
                    [($.block ($.section {#$.title <title>
                                          #$.content <content>}))]
                    
                    ["Grant of Copyright License"
                     grant.copyright]
                    
                    ["Grant of Patent License"
                     (grant.patent (get@ #license.patent-retaliation? termination))]
                    
                    ["Effective Date for the Grants"
                     grant.date]

                    ["Grant Termination"
                     (grant.termination (get@ #license.termination-period termination)
                                        (get@ #license.grace-period termination))]

                    ["No Retroactive Effect of Termination"
                     grant.no-retroactive-termination])))))

(def: #export limitation
  Text
  (`` (format (~~ (template [<title> <content>]
                    [($.block ($.section {#$.title <title>
                                          #$.content <content>}))]
                    
                    ["Limitations on Grant Scope"
                     limitation.grant]
                    
                    ["Limitations on Trademarks"
                     limitation.trademark]

                    [(format "Limitations on " ($.plural _.secondary-license))
                     limitation.secondary-licenses])))))

(def: #export assurance
  Text
  (`` (format (~~ (template [<title> <content>]
                    [($.block ($.section {#$.title <title>
                                          #$.content <content>}))]
                    
                    ["Representation"
                     assurance.representation]
                    
                    ["Fair Use"
                     assurance.fair-use])))))

(def: #export (liability value)
  (-> Liability Text)
  (`` (format (~~ (template [<title> <condition> <content>]
                    [(if <condition>
                       ($.block ($.section {#$.title <title>
                                            #$.content <content>}))
                       "")]

                    ["Disclaimer of Warranty"
                     on
                     liability.warranty]
                    
                    ["Limitation of Liability"
                     on
                     liability.limitation]
                    
                    ["Litigation"
                     on
                     liability.litigation]
                    
                    ["Accepting Warranty or Additional Liability"
                     (get@ #license.can-accept? value)
                     liability.can-accept]

                    ["High Risk Activities"
                     (get@ #license.disclaim-high-risk? value)
                     liability.disclaim-high-risk])))))

(def: #export (distribution distribution)
  (-> Distribution Text)
  (`` (format (~~ (template [<title> <condition> <content>]
                    [(if <condition>
                       ($.block ($.section {#$.title <title>
                                            #$.content <content>}))
                       "")]
                    
                    [(format "Distribution of a " _.source-code-form)
                     on
                     distribution.source-code-form]
                    
                    [(format "Distribution of an " _.object-form)
                     on
                     distribution.object-form]
                    
                    [(format "Distribution of an " _.extension)
                     (or (get@ #license.can-re-license? distribution)
                         (get@ #license.can-multi-license? distribution))
                     (distribution.extension distribution)])))))

(def: #export (commercial value)
  (-> Commercial Text)
  (`` (format (~~ (template [<title> <condition> <content>]
                    [(if <condition>
                       ($.block ($.section {#$.title <title>
                                            #$.content <content>}))
                       "")]

                    ["Non-Commerciality"
                     (not (get@ #license.can-sell? value))
                     commercial.cannot-sell]

                    [(format _.contributor " Attribution")
                     (get@ #license.require-contributor-credit? value)
                     commercial.require-contributor-attribution]

                    [(format _.contributor " Endorsement")
                     (not (get@ #license.allow-contributor-endorsement? value))
                     commercial.disallow-contributor-endorsement]
                    )))))

(def: #export (extension value)
  (-> Extension Text)
  (let [[show? document] (case (get@ #license.notification-period value)
                           (#.Some period)
                           [true (extension.notification-requirement period)]

                           #.None
                           [false ""])]
    (`` (format (~~ (template [<condition> <title> <content>]
                      [(if <condition>
                         ($.block ($.section {#$.title <title>
                                              #$.content <content>}))
                         "")]

                      [(get@ #license.same-license? value) "License Retention"
                       ($.paragraph (list\compose extension.sharing-requirement
                                                  extension.license-conflict-resolution))]
                      
                      [(get@ #license.must-be-distinguishable? value) (format _.extension " Distinctness")
                       extension.distinctness-requirement]
                      
                      [show? (format _.source-code-form " Availability")
                       document]
                      
                      [(get@ #license.must-describe-modifications? value) (format "Description of " ($.plural _.modification))
                       extension.description-requirement]))))))

(def: #export (attribution value)
  (-> Attribution Text)
  (let [copyright-notice (format "Attribution Copyright Notice: " (get@ #license.copyright-notice value))
        phrase (case (get@ #license.phrase value)
                 (#.Some phrase)
                 (format text.new-line "Attribution Phrase: " phrase text.new-line)

                 #.None
                 "")
        url (format text.new-line "Attribution URL: " (get@ #license.url value))
        image (case (get@ #license.image value)
                (#.Some image)
                (format text.new-line "Attribution Image: " image)

                #.None
                "")]
    (format copyright-notice
            phrase
            url
            image)))

(def: #export (miscellaneous identified?)
  (-> Bit Text)
  (`` (format (~~ (template [<title> <condition> <content>]
                    [(if <condition>
                       ($.block ($.section {#$.title <title>
                                            #$.content <content>}))
                       "")]

                    ["Entire Agreement"
                     on
                     miscellaneous.entire-agreement]

                    ["Relationship of Parties"
                     on
                     miscellaneous.relationship-of-parties]

                    ["Independent Development"
                     on
                     miscellaneous.independent-development]

                    ["Consent To Breach Not Waiver"
                     on
                     miscellaneous.not-waiver]
                    
                    ["Severability"
                     on
                     miscellaneous.severability]

                    ["Export Restrictions"
                     on
                     miscellaneous.export-restrictions]

                    [(format "Versions of " _.license)
                     identified?
                     miscellaneous.new-versions]
                    )))))

(def: black-list-spacing (format text.new-line text.new-line))

(def: #export (license value)
  (-> License Text)
  (let [identification (|> value
                           (get@ #license.identification)
                           (maybe\map ..identification)
                           (maybe.default ""))
        identified? (case (get@ #license.identification value)
                      (#.Some _)
                      true

                      #.None
                      false)]
    (`` (format ($.block identification)
                ($.block (notice.copyright (get@ #license.copyright-holders value)))
                
                (case (get@ #license.black-lists value)
                  #.Nil
                  ""

                  black-lists
                  ($.block ($.section {#$.title (format "Denial of " _.license)
                                       #$.content (|> black-lists
                                                      (list\map black-list.black-list)
                                                      (text.join-with ..black-list-spacing))})))
                
                ($.section {#$.title "Definitions"
                            #$.content (|> definition.all
                                           (list\map (|>> ..definition $.block))
                                           (text.join-with ""))})

                ($.block ($.section {#$.title (format "Acceptance of " _.license)
                                     #$.content limitation.acceptance}))

                (..grant (get@ #license.termination value))
                ..limitation
                ..assurance

                ($.block ($.section {#$.title (format _.submission " of " ($.plural _.contribution))
                                     #$.content submission.contribution}))

                (..liability (get@ #license.liability value))
                (..distribution (get@ #license.distribution value))
                (..commercial (get@ #license.commercial value))
                (..extension (get@ #license.extension value))

                (|> value
                    (get@ #license.attribution)
                    (maybe\map (|>> ..attribution
                                    ["Attribution Information"]
                                    $.section
                                    $.block))
                    (maybe.default ""))

                (..miscellaneous identified?)

                (addendum.output (get@ #license.addendum value))
                
                notice.end-of-license
                ))))