
-- {-# LANGUAGE OverloadedStrings #-}
-- {-# LANGUAGE RecordWildCards #-}
-- {-# LANGUAGE MultiWayIf #-}


import Development.Shake
import Development.Shake.FilePath

-- import Development.Shake.Util
-- import Development.Shake.Command

-- import Control.Applicative ((<$>))
import qualified Control.Monad as M

-- import Data.Traversable


-- import Text.Regex.Posix
-- import Data.Maybe (fromMaybe)




main :: IO ()





main = shakeArgs shakeOptions {
  -- shakeFiles="."
  shakeFiles="_build"
  -- , shakeProgress=progressSimple
  } $ do



  phony "clean" $ (do {
                      -- liftIO $ removeFiles "." [...]
                      ; removeFilesAfter "." $ tail [
                          undefined
                          , "//*.html"
                          , "//*.dbkhtml"
                          , "//html"
                          , "//dbkhtml"
                          
                          , "//*.fo", "//*.pdf"
                          , "//pdf"
                          , "//*.dbk", "//*.dbk+", "//*.dbkxi"
                          
                          , "snippets"
                          , "_snippet_*"
                          
                          ]



                      -- formerly in pire dir - but they really should go here

                      -- ; unit $ cmd (Cwd "docs") Shell $ words $ unwords $ [ "rm -rf ./doctest-snippets" ]
                      
                      -- ; unit $ cmd (Cwd "docs") Shell $ words $ unwords $ [ "rm -f *.dyn_hi" ]
                      -- ; unit $ cmd (Cwd "docs") Shell $ words $ unwords $ [ "rm -f *.dyn_o" ]
                      
                      -- ; unit $ cmd (Cwd "docs") Shell $ words $ unwords $ [ "rm -f *.hi" ]
                      -- ; unit $ cmd (Cwd "docs") Shell $ words $ unwords $ [ "rm -f *.o" ]
                      -- ; unit $ cmd (Cwd "docs") Shell $ words $ unwords ["rm -f ./_*.hs" ]
                                            
                      
                      -- -- create w/ build.sh -B -V writedoctests
                      -- ; unit $ cmd (Cwd "docs") Shell $ words $ unwords ["rm -f ./_*.hs" ]
                      -- ; unit $ cmd (Cwd "docs") Shell $ words $ unwords ["rm -f ./_*.hs" ]


                      
                      ; unit $ cmd Shell $ words $ unwords [ "rm -rf ./doctest-snippets" ]
                      
                      ; unit $ cmd Shell $ words $ unwords [ "rm -f *.dyn_hi" ]
                      ; unit $ cmd Shell $ words $ unwords [ "rm -f *.dyn_o" ]
                      
                      ; unit $ cmd Shell $ words $ unwords [ "rm -f *.hi" ]
                      ; unit $ cmd Shell $ words $ unwords [ "rm -f *.o" ]
                      ; unit $ cmd Shell $ words $ unwords ["rm -f ./_*.hs" ]
                                            
                      
                      -- create w/ build.sh -B -V writedoctests
                      ; unit $ cmd Shell $ words $ unwords ["rm -f ./_*.hs" ]
                      ; unit $ cmd Shell $ words $ unwords ["rm -f ./_*.hs" ]




         })



  -- shake clean
  phony "shclean" $ do {

    -- formerly in pire
    -- ; unit $ cmd (Cwd "docs") Shell $ words $ unwords [ "rm -rf _shake" ]
    -- ; unit $ cmd (Cwd "docs") Shell $ words $ unwords [ "rm -rf _build" ]


    ; unit $ cmd Shell $ words $ unwords [ "rm -rf _shake" ]
    ; unit $ cmd Shell $ words $ unwords [ "rm -rf _build" ]


    }






  phony "oclean" $
    (do
         -- liftIO $ removeFiles "." [...]
         ; removeFilesAfter "." $ tail [
           undefined

           , "//*.hi"
           , "//*.o"

           ]
    )



  -- phony "sclean" $
  --   (do
  --        ; removeFilesAfter "." $ tail [
  --          undefined

  --          , "_snippet_*"
             


  --          ]
  --   )




  -- "aka fonts clean"
  phony "fclean" $ do {
    -- maybe
    -- need ["clean"]

    ; removeFilesAfter "." $ tail [
       undefined
       , "fonts/lucidatypewriter"
       , "fonts/palatino"
       , "fonts/palatinoi"
         
       , "fonts/dejavu"
       , "fonts/dejavui"
       , "fonts/dejavusansmono"
         
         -- , "urwclassico"
       , "fcreate"
       ]
    }

  
  "snippets" %> \c ->
    (do
         -- ; let hs = "support" </> (dropDirectory1 c) <.> ".hs"
         -- ; let hs = (dropDirectory1 c) <.> ".hs"
         ; let hs = c <.> ".hs"

         ; need [hs]

         ; () <- cmd Shell $ tail [
           undefined
           , "ghc"

             , "-O2 -threaded"

             -- , "-outputdir=_build"

             -- , "-cpp"
             -- , "-DShakeDep"

             , "-o ", c
             ,  hs
             ]

           ; return ()
      )






  phony "allsnippets" $
    (do
         ; need ["snippets"]

         -- ; let p = "~/website/static/pire"

         -- ; () <- cmd Shell [ "cp", "./pire.pdf" , p]
         -- ; () <- cmd Shell [ "cp", "-r",  "./css" , p]

         ; () <- cmd Shell [ "snippets"
                           , "--hsfile", "../src/docs.hs"
                           , "--nicer"
                           ]

         ; return ()
    )


  -- --------------------------------------------------

    -- the program
  "doctest-snippets" %> \c ->
    (do
         -- ; let hs = "support" </> (dropDirectory1 c) <.> ".hs"
         -- ; let hs = (dropDirectory1 c) <.> ".hs"
         ; let hs = c <.> ".hs"

         ; need [hs]

         ; () <- cmd Shell $ words $ unwords $ tail [
           undefined
           , "ghc"
           
             , "-O2 -threaded"

             -- , "-outputdir=_build"
             -- , "-cpp"
             -- , "-DShakeDep"
             , "-o ", c
             ,  hs
             ]
           ; return ()
      )


  "_*.hs" %> \hs ->
    (do
         -- ; let hs = "support" </> (dropDirectory1 c) <.> ".hs"
         -- ; let hs = (dropDirectory1 c) <.> ".hs"
         
         ; let adoc = (tail hs) -<.> "adoc"
         
         ; need ["doctest-snippets"]
         ; need [adoc]
         
         ; () <- cmd Shell $ words $ unwords $ tail [
           undefined
           , "doctest-snippets"
             
           , "--adoc", adoc
           , ">", hs
                   
           ]
     
         ; return ()
    )




  phony "writedoctests" $
    (do
         ; let ch = tail [
                 undefined
                 , "parsec.adoc"
                 , "tour.adoc"
                 , "backtracking+mimicry.adoc"
                 , "zipperimpl.adoc"
                 ]
         ; let ch' = (('_':) . (-<.> "hs")) <$> ch

         
         -- ; let chapters' = chapters

         ; need ch'    

         ; M.mapM (\c ->

                     (do
                          ; () <- cmd Shell [ "cp"
                                            -- , c, "../tests"
                                            , c, "../src"
                                            ]
                          ; return ()
                     )

                  ) ch'
     
         -- ; let chapters = ["parsec.adoc", "tour.adoc"]
                           -- ; let chapters' = ((\ch -> '_':(ch -<.> "hs")) <$> chapters)
                           
                           -- ; need chapters'
                           
                     
         ; return ()
    )




    -- --------------------------------------------------

            
    -- test w/
    -- -- $ (cd ~/etc/lib-pi-forall/ && find . -iname "*" -print0 -type f | egrep -z -Z -v "^.$|\.cabal-sandbox|/dist|cabal\.sandbox\.config" | xargs -0 -L 1)
    -- -- $ (cd ~/etc/lib-pi-forall/ && find . -iname "*" -print0 -type f | egrep -z -Z -v "^.$|\.cabal-sandbox|/dist" | rsync -a -e ssh --delete  --progress --files-from=- -0 ./ ~/website/static/lib-pi-forall)

    -- cf sync

    -- -- only by egrep -v "^.$" as well are the empty dir dist/ and cabal.sandbox.config excluded
    -- -- ie. normally the sneak in by . result of find
    

  phony "web-lib-pi-forall" $ do {
            
    ; () <- cmd Shell [ "(cd /home/rx/etc/lib-pi-forall && find . -iname \"*\" -print0 -type f"
                      ,"| egrep -z -Z -v \"^\\.$|\\.cabal-sandbox|/dist|cabal\\.sandbox\\.config\""

                       -- ,"| xargs -0 -L 1"
                       -- ,"| rsync -a -e ssh --delete  --progress --files-from=- ./ /home/rx/website/static/lib-pi-forall/)"
                      ,
                       -- "| rsync -a -e ssh --delete-missing-args --delete --progress --files-from=- -0 ./ /home/rx/website/static/lib-pi-forall/)"

                       
                       -- --exclude='*/' removes empty dirs/ at least - why is that transferred in the first place ?
                       -- --exclude='' removes empty dirs/ at least - why is that transferred in the first place ?
                       "| rsync -a -e ssh --delete --progress --files-from=- -0 ./ /home/rx/website/static/lib-pi-forall/)"
                      ]


            -- create tgz
    ; () <- cmd Shell [
       "(cd /home/rx/website/static && rm -rf lib-pi-forall.tgz && tar cvpzf lib-pi-forall.tgz lib-pi-forall)"
       ]

            
            -- provide lib-pi-forall.cabal file
    ; () <- cmd Shell [
       "cp /home/rx/etc/lib-pi-forall/lib-pi-forall.cabal /home/rx/website/static"
       ]




            
    ; return ()


      
    }




  phony "web" $ do {
    ; need ["pire.pdf"]
    ; need ["pire.html"]
    ; let p = "~/website/static/pire"
          
          
    ; () <- cmd Shell [ "cp", "./pire.pdf" , p]
    ; () <- cmd Shell [ "cp", "./pire.html" , p]
    ; () <- cmd Shell [ "cp", "-r",  "./css" , p]

    ; need ["web-lib-pi-forall"]
            

            
      -- jan2016 - sync website to website_ 
      -- as that is, what's used on web
      -- (backup.py -t web -web copies both: website, and website_)
      -- and recall: /etc/init.d/website starts the srv in /home/rx/website_ 
      -- (ie. website_ is used on the srv)
    ; () <- cmd Shell [

                
        -- "(cd /home/rx/website && sync)"


        -- july 2016
        -- "(cd /home/rx/website && ./sync.hs -t /home/rx/website_)"
        "(cd /home/rx/work/servant && ./sync.hs -t /home/rx/website_)"


        

        ]

      
    ; return ()


      
    }


  -- create link
  "html" %> \lnk -> do
    let html = "pire.html"
    need [html]
    () <- cmd Shell $ words $ unwords $ tail [
      undefined
      , "ln -s -f "++html++" ./" ++ lnk
      ]
    return ()

  -- create link
  "dbkhtml" %> \lnk -> do
    let dh = "pire.dbkhtml"
    need [dh]
    () <- cmd Shell $ tail [
      undefined
      , "ln -s -f "++dh++" ./" ++ lnk
      ]
    return ()





  -- asciidoctor html
  "*.html" %> \h -> do
    let ad = h -<.> "adoc"
    need [ad]
    () <- cmd Shell $ words $ unwords $ tail [
      undefined
      , "asciidoctor -a linkcss -a stylesdir=css -a stylesheet=pire.css "++ad

      -- , "asciidoctor -b xhtml5 -a linkcss -a stylesdir=css -a stylesheet=pire.css "++ad
      ]
    return ()


  -- w/ deps - ! should really get them automatically
  "pire.html" %> \h -> do
    let ad = h -<.> "adoc"
    need [ad]
    -- deps
    need ["intro.adoc"
         , "tour.adoc"
         , "changes.adoc"
         ]
    () <- cmd Shell $ words $ unwords $ tail [
      undefined
      , "asciidoctor -a linkcss -a stylesdir=css -a stylesheet=pire.css "++ad
        -- , "asciidoctor -b xhtml5 -a linkcss -a stylesdir=css -a stylesheet=pire.css "++ad
      ]
    return ()


  -- dbk html
  "*.dbkhtml" %> \h -> do

    let plus = h -<.> "dbk+"

    -- let dbk = dropExtension tex
    need [plus]

    () <- cmd Shell $ tail [

      undefined

      , "xsltproc --xinclude --xincludestyle --output "++h++" --stringparam use.extensions 0 ./html.xsl "++plus
      ]

    return ()




  -- create link pdf -> pire.pdf
  "pdf" %> \lnk -> do
    let pdf = "pire.pdf"
    need [pdf]
    () <- cmd Shell $ tail [
      undefined
      , "ln -s -f "++pdf++" ./" ++ lnk
      ]
    return ()



  -- need fonts as well, but rather build them by hand
  "*.pdf" %> \pdf -> do
    let fo = pdf -<.> "fo"

    need [fo]
    need ["cfg"]

    -- but rather do them by hand
    -- need ["fcreate"]

    () <- cmd Shell $ tail [
      undefined
      , "fop -c cfg -fo "++fo++" -pdf "++pdf
      ]
    return ()





  "*.fo" %> \fo -> do
    let p = fo -<.> "dbk+"
    need [p]
    need ["fo.xsl"]
    () <- cmd Shell $ tail [
      undefined
      , "xsltproc --xinclude --xincludestyle --output "++fo++" --stringparam fop1.extensions 1 fo.xsl "++p
      ]
    return ()







  "*.dbk" %> \d -> do

    -- turn off preprocessing, so that the html can be used for cut & paste
    -- still needed ?

    let ad = d -<.> "adoc"
    -- -- let dbk = dropExtension x

    need [ad]

    () <- cmd Shell $ tail [

      undefined

      , "asciidoctor -b docbook5 -o "++d++" "++ad


        -- dbk5 should be the default for dbk later
        -- , "asciidoctor -b docbook "++ad

      ]

    return ()






  "*.dbk+" %> \p -> do

    -- turn off preprocessing, so that the html can be used for cut & paste
    -- still needed ?

    let xi = p -<.> "dbkxi"

    -- let dbk = dropExtension tex
    need [xi]

    () <- cmd Shell $ tail [

      undefined

      , "saxonb-xslt -xi -s:"++xi++" -xsl:preproc.xsl -o:"++p
      ]

    return ()




  "*.dbkxi" %> \xi -> do

    let dbk = xi -<.> "dbk"

    -- let dbk = dropExtension tex
    need [dbk]


    () <- cmd Shell $ tail [

      undefined

      -- want xincludes and just plain section tags...
      , "xmllint --xinclude "++dbk++" | saxonb-xslt -s:- -xsl:rm-xml-base-etc.xsl -o:"++xi
      ]

    return ()




  -- phony "fonts" $ do
  "fcreate" %> \f ->
    (do

         ; need $ tail
           [
             undefined
           , "fonts/lucidatypewriter"
           , "fonts/palatino"
           , "fonts/palatinoi"
           , "fonts/dejavu"
           , "fonts/dejavui"
           , "fonts/dejavusansmono"
             -- , "optima"
             -- , "urwclassico"
           ]

         -- touch a file fonts-created as an indicator that the fonts
         -- have been created,
         -- as opposed to using a phony target and creating them
         -- over and over again

         ; () <- cmd Shell $ tail [
           undefined
           , "touch "++f
           ]


         ; return ()
    )



  "fonts/lucidatypewriter" %> \f ->
      (do

           ; () <- cmd Shell $ tail [

             undefined
             , "fop-ttfreader ./fonts/LucidaTypewriter.ttf "++f
             ]

           ; return ()
      )

  "fonts/palatino" %> \f ->
    (do

         ; () <- cmd Shell $ tail [
           undefined
           , "fop-ttfreader ./fonts/PalatinoLinotype.ttf "++f
           ]


         ; return ()

    )

  "fonts/palatinoi" %> \f ->
    (do

         ; () <- cmd Shell $ tail [
           undefined
           , "fop-ttfreader ./fonts/PalatinoLinotypeItalic.ttf "++f
           ]

         ; return ()
    )



  "fonts/dejavu" %> \f -> do {
    ; () <- cmd Shell $ tail [
       undefined
       , "fop-ttfreader /usr/share/fonts/truetype/ttf-dejavu/DejaVuSerif.ttf "++f
       ]
    ; return ()
    }


  "fonts/dejavui" %> \f -> do {
    ; () <- cmd Shell $ tail [
       undefined
       , "fop-ttfreader /usr/share/fonts/truetype/ttf-dejavu/DejaVuSerif-Italic.ttf "++f
       ]
    ; return ()
    }



  "fonts/dejavusansmono" %> \f -> do {
    ; () <- cmd Shell $ tail [
       undefined
       , "fop-ttfreader /usr/share/fonts/truetype/ttf-dejavu/DejaVuSansMono.ttf "++f
       ]
    ; return ()
    }





    -- "urwclassico" %> \f -> do
    --   () <- cmd Shell $ tail [
    --     undefined
    --     , "./my-fop-pfmreader ./fonts/uopr8a.pfm "++f
    --     ]
    --   return ()





{-
  remark: I often write lists as

    tail $
    [
      undefined
      , item1
      , item2
      , etc
      ]

  rather than

    [
      item1
      , item2
      , etc
      ]

  that way I can more easily comment out items (lines),
  or move them up/down, as all items start w/ a comma then, and
  the first item is not in any way special
 -}





  ; "_build/gitignore" %> \c -> do {



    -- ; let hs = "support" </> (dropDirectory1 c) <.> ".hs"
    -- ; hs <- return $ (dropDirectory1 c) <.> ".hs"

    -- -- ; hs <- return $ c <.> ".hs"
    ; let hs = (dropDirectory1 c) <.> ".hs"

    ; need [hs]

    ; () <- cmd Shell $ tail [
      undefined
      , "ghc"
      , "-O2 -threaded"
        -- , "-outputdir=_build"
      , "-cpp"


        -- -- , if ShakeDep `elem` flgs then
        -- --     "-DShakeDep" else ""
        -- -- , if Min `elem` flgs then
        -- --     "-DMin" else ""
      , "-o ", c
      ,  hs
      ]


    ; return ()
    }





  ; ".gitignore" %> \c -> do {
    -- ; need ["gitignore"]
    ; need ["_build/gitignore"]
    ; () <- do {
       ; cmd Shell $ tail [
          undefined
          ,"./_build/gitignore"
           -- ,"./gitignore"
          , ">"
          , c
          ]
       }
    ; return ()
    }


