module Controller.Angular
  ( JSOpt(..)
  , jsURL
  , angular
  
  , angularRequest
  ) where
import Control.Arrow (second)
import qualified Data.ByteString as BS
import qualified Data.ByteString.Builder as BSB
import Data.Default.Class (Default(..))
import Network.HTTP.Types (hUserAgent, QueryLike(..))
import qualified Network.Wai as Wai
import qualified Text.Regex.Posix as Regex
import Has
import Action
import HTTP (encodePath')
import HTTP.Request
import View.Angular
import Web
import Web.Service (Web, getWebVersion)
data JSOpt
  = JSDisabled
  | JSDefault
  | JSEnabled
  deriving (Eq, Ord)
instance Default JSOpt where
  def = JSDefault
instance Monoid JSOpt where
  mempty = JSDefault
  mappend JSDefault j = j
  mappend j _ = j
instance QueryLike JSOpt where
  toQuery JSDisabled = [("js", Just "0")]
  toQuery JSDefault = []
  toQuery JSEnabled = [("js", Just "1")]
jsEnable :: Bool -> JSOpt
jsEnable False = JSDisabled
jsEnable True = JSEnabled
jsURL
    :: JSOpt 
    -> Wai.Request
    
    
    
    -> (JSOpt, BSB.Builder)
    
    
jsURL js req =
    second (encodePath' (Wai.pathInfo req) . (toQuery js ++))
        $ unjs
        $ Wai.queryString req
  where
    unjs [] = (JSDefault, [])
    unjs (("js", v) : q) = (jsEnable (boolParameterValue v), snd $ unjs q)
    unjs (x : q) = second (x :) $ unjs q
browserBlacklist :: Regex.Regex
browserBlacklist = Regex.makeRegex
  ("^Mozilla/.* \\(.*\\<(MSIE [0-9]\\.[0-9]|AppleWebKit/.* Version/[0-5]\\..* Safari/)" :: String)
enableAngular :: JSOpt -> Wai.Request -> Bool
enableAngular JSDisabled = const False
enableAngular JSDefault = not . any (Regex.matchTest browserBlacklist) . lookupRequestHeader hUserAgent
enableAngular JSEnabled = const True
angularRequest :: Wai.Request -> Maybe BSB.Builder
angularRequest req =
    if enableAngular jsopt req
    then Just nojs
    else Nothing
  where (jsopt, nojs) = jsURL JSDisabled req
angularResult :: BS.ByteString -> BSB.Builder -> RequestContext -> IO ()
angularResult version nojs reqCtx = do
  cssDeps <- (:[]) <$> makeWebFilePath "all.min.css"
  jsDeps <- (:[]) <$> makeWebFilePath "all.min.js"
  result $ okResponse [] (htmlAngular version cssDeps jsDeps nojs reqCtx)
angular :: Handler ()
angular = do
    (servWeb :: Web) <- peek
    let version = getWebVersion servWeb
    (b :: Maybe BSB.Builder) <- peeks angularRequest
    mapM_ (focusIO . angularResult version) b