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

module Data.API.Doc.Dir
    ( dirHtml
    ) where

import           Data.API.Doc.Types
import           Data.API.Doc.Subst
import           Data.List
import           Data.Ord
import           Data.Char


-- | Generate a web page documenting all the 'Call's in a web
-- application
dirHtml :: DocInfo -> Dict -> [Call] -> String
dirHtml :: DocInfo -> Dict -> [Call] -> String
dirHtml DocInfo
di Dict
dct [Call]
cls = [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
    [ Dict -> String
container_open                 Dict
dct
    , [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ ((String, [Call]) -> String) -> [(String, [Call])] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (DocInfo -> Dict -> (String, [Call]) -> String
resourceHtml DocInfo
di  Dict
dct) ([(String, [Call])] -> [String]) -> [(String, [Call])] -> [String]
forall a b. (a -> b) -> a -> b
$ [Call] -> [(String, [Call])]
aggregate [Call]
cls
    ]

aggregate :: [Call] -> [(String,[Call])]
aggregate :: [Call] -> [(String, [Call])]
aggregate = ([(String, Call)] -> (String, [Call]))
-> [[(String, Call)]] -> [(String, [Call])]
forall a b. (a -> b) -> [a] -> [b]
map [(String, Call)] -> (String, [Call])
forall a b. [(a, b)] -> (a, [b])
f ([[(String, Call)]] -> [(String, [Call])])
-> ([Call] -> [[(String, Call)]]) -> [Call] -> [(String, [Call])]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((String, Call) -> (String, Call) -> Bool)
-> [(String, Call)] -> [[(String, Call)]]
forall a. (a -> a -> Bool) -> [a] -> [[a]]
groupBy (String, Call) -> (String, Call) -> Bool
forall a b b. Eq a => (a, b) -> (a, b) -> Bool
eq ([(String, Call)] -> [[(String, Call)]])
-> ([Call] -> [(String, Call)]) -> [Call] -> [[(String, Call)]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((String, Call) -> (String, Call) -> Ordering)
-> [(String, Call)] -> [(String, Call)]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (((String, Call) -> String)
-> (String, Call) -> (String, Call) -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing (String, Call) -> String
forall a b. (a, b) -> a
fst) ([(String, Call)] -> [(String, Call)])
-> ([Call] -> [(String, Call)]) -> [Call] -> [(String, Call)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Call -> (String, Call)) -> [Call] -> [(String, Call)]
forall a b. (a -> b) -> [a] -> [b]
map Call -> (String, Call)
x_r
  where
    x_r :: Call -> (String, Call)
x_r cl :: Call
cl@Call{Bool
String
[String]
[Sample]
[View]
[Param]
[Header]
Maybe (APIType, String)
call_samples :: Call -> [Sample]
call_views :: Call -> [View]
call_params :: Call -> [Param]
call_body :: Call -> Maybe (APIType, String)
call_headers :: Call -> [Header]
call_auth_required :: Call -> Bool
call_description :: Call -> String
call_path :: Call -> [String]
call_http_method :: Call -> String
call_samples :: [Sample]
call_views :: [View]
call_params :: [Param]
call_body :: Maybe (APIType, String)
call_headers :: [Header]
call_auth_required :: Bool
call_description :: String
call_path :: [String]
call_http_method :: String
..} =
        case [String]
call_path of
          []     -> (String
"/" ,Call
cl)
          String
rsrc:[String]
_ -> (String
rsrc,Call
cl)

    eq :: (a, b) -> (a, b) -> Bool
eq (a
x,b
_) (a
y,b
_)   = a
xa -> a -> Bool
forall a. Eq a => a -> a -> Bool
==a
y

    f :: [(a, b)] -> (a, [b])
f []             = String -> (a, [b])
forall a. HasCallStack => String -> a
error String
"Data.API.Doc.Dir.aggregate"
    f ((a
rsrc,b
cl):[(a, b)]
ps) = (a
rsrc,b
clb -> [b] -> [b]
forall a. a -> [a] -> [a]
:((a, b) -> b) -> [(a, b)] -> [b]
forall a b. (a -> b) -> [a] -> [b]
map (a, b) -> b
forall a b. (a, b) -> b
snd [(a, b)]
ps)


resourceHtml :: DocInfo -> Dict -> (String,[Call]) -> String
resourceHtml :: DocInfo -> Dict -> (String, [Call]) -> String
resourceHtml DocInfo
di Dict
dct (String
rsc,[Call]
cls) = [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
    [ Dict -> String
resource_heading      Dict
r_dct
    , Dict -> String
ul_open               Dict
r_dct
    , [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [ DocInfo -> Dict -> Call -> String
callHtml DocInfo
di  Dict
r_dct Call
cl | Call
cl<-[Call]
cls ]
    , Dict -> String
ul_close              Dict
r_dct
    ]
  where
    r_dct :: Dict
r_dct = Dict -> String -> Dict
resource_dict Dict
dct String
rsc

resource_dict :: Dict -> String -> Dict
resource_dict :: Dict -> String -> Dict
resource_dict Dict
dct String
rsc = ([(String, String)] -> Dict -> Dict)
-> Dict -> [(String, String)] -> Dict
forall a b c. (a -> b -> c) -> b -> a -> c
flip [(String, String)] -> Dict -> Dict
extDict Dict
dct
    [ (,) String
"RESOURCE-HEADING"    String
rsc
    ]

callHtml :: DocInfo -> Dict -> Call -> String
callHtml :: DocInfo -> Dict -> Call -> String
callHtml DocInfo
di Dict
dct Call
cl = Dict -> String
call (Dict -> String) -> Dict -> String
forall a b. (a -> b) -> a -> b
$ DocInfo -> Dict -> Call -> Dict
call_dict DocInfo
di Dict
dct Call
cl

call_dict :: DocInfo -> Dict -> Call -> Dict
call_dict :: DocInfo -> Dict -> Call -> Dict
call_dict DocInfo
di Dict
dct Call{Bool
String
[String]
[Sample]
[View]
[Param]
[Header]
Maybe (APIType, String)
call_samples :: [Sample]
call_views :: [View]
call_params :: [Param]
call_body :: Maybe (APIType, String)
call_headers :: [Header]
call_auth_required :: Bool
call_description :: String
call_path :: [String]
call_http_method :: String
call_samples :: Call -> [Sample]
call_views :: Call -> [View]
call_params :: Call -> [Param]
call_body :: Call -> Maybe (APIType, String)
call_headers :: Call -> [Header]
call_auth_required :: Call -> Bool
call_description :: Call -> String
call_path :: Call -> [String]
call_http_method :: Call -> String
..} = ([(String, String)] -> Dict -> Dict)
-> Dict -> [(String, String)] -> Dict
forall a b c. (a -> b -> c) -> b -> a -> c
flip [(String, String)] -> Dict -> Dict
extDict Dict
dct
    -- calls
    [ (,) String
"CALL-URL"          (String -> (String, String)) -> String -> (String, String)
forall a b. (a -> b) -> a -> b
$ DocInfo -> String -> [String] -> String
doc_info_call_url DocInfo
di String
call_http_method [String]
call_path
    , (,) String
"METHOD-CLASS"      (String -> (String, String)) -> String -> (String, String)
forall a b. (a -> b) -> a -> b
$ (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower String
mth_s
    , (,) String
"METHOD"            (String -> (String, String)) -> String -> (String, String)
forall a b. (a -> b) -> a -> b
$ String
mth_s
    , (,) String
"PATH"              (String -> (String, String)) -> String -> (String, String)
forall a b. (a -> b) -> a -> b
$ Char
'/' Char -> String -> String
forall a. a -> [a] -> [a]
: [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (String -> [String] -> [String]
forall a. a -> [a] -> [a]
intersperse String
"/" [String]
call_path)
    , (,) String
"BODY-TYPE"         (String -> (String, String)) -> String -> (String, String)
forall a b. (a -> b) -> a -> b
$ String
-> ((APIType, String) -> String)
-> Maybe (APIType, String)
-> String
forall b a. b -> (a -> b) -> Maybe a -> b
maybe String
"&mdash;" (DocInfo -> APIType -> String
renderAPIType DocInfo
di (APIType -> String)
-> ((APIType, String) -> APIType) -> (APIType, String) -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (APIType, String) -> APIType
forall a b. (a, b) -> a
fst) Maybe (APIType, String)
call_body
    ]
  where
    mth_s :: String
mth_s = String
call_http_method
--    cvt   = T.unpack . _APINodeName

container_open :: Dict -> String
container_open :: Dict -> String
container_open Dict
dct = Dict -> [String] -> String
prep Dict
dct
    [ String
"<h2>"
    , String
"   <<TITLE>>"
    , String
"   <span class='tagline'><<TAGLINE>></span>"
    , String
"</h2>"
    , String
"<strong>Endpoint: </strong><<ENDPOINT>>"
    , String
"<br>"
    , String
"<div id='toc'>"
    , String
"   <div id='app-description'>"
    , String
"      <p><<SUMMARY>></p>"
    , String
"   </div>"
    , String
"   <hr/>"
    , String
"   <br>"
    , String
"   <h3 class='section-title'>"
    , String
"      API Resources for This Application"
    , String
"   </h3>"
    ]

resource_heading :: Dict -> String
resource_heading :: Dict -> String
resource_heading Dict
dct = Dict -> [String] -> String
prep Dict
dct
    [ String
"   <h5 class='tag'><<RESOURCE-HEADING>></h5>"
    ]

ul_open :: Dict -> String
ul_open :: Dict -> String
ul_open Dict
dct = Dict -> [String] -> String
prep Dict
dct
    [ String
"   <ul class='list resource-list'>"
    ]

call :: Dict -> String
call :: Dict -> String
call Dict
dct = Dict -> [String] -> String
prep Dict
dct
    [ String
"      <li >"
    , String
"         <a class='reflink' href='<<CALL-URL>>'>"
    , String
"         <span class='<<METHOD-CLASS>>'><<METHOD>></span>"
    , String
"         <<PATH>>"
    , String
"         </a>"
    , String
"         <div class='post-data' ><<BODY-TYPE>></div>"
    , String
"      </li>"
    ]

ul_close :: Dict -> String
ul_close :: Dict -> String
ul_close Dict
dct = Dict -> [String] -> String
prep Dict
dct
    [ String
"   </ul>"
    ]