module Dingo.Internal.Session
       ( SessionT
       , SessionState
       , addWidget
       , getWidgetStateM
       , lookupResource -- Re-export
       , newWidgetId
       , registerCallback
       , registerResourceBundle
       , registerWidgetType
       , runCallback
       , runSessionT
       , setWidgetStateM
       ) where

import           Data.Aeson (Value)
import           Data.HashMap.Strict (HashMap)
import qualified Data.HashMap.Strict as H
import           Data.Label.PureM (modify)
import           Data.Monoid (Monoid(..))
import           Dingo.Internal.Base
import           Dingo.Internal.CallbackTypes
import           Dingo.Internal.SessionTypes
import           Dingo.Internal.WidgetSet

-- Run callback.
runCallback :: CallbackId -> HashMap WidgetId Value -> SessionT WrapCallback IO CallbackState
runCallback callbackId encodedStatesFromBrowser = SessionT $ do
  -- We'll update the state of all the widgets in response to the
  -- updates we've received from the browser.
  modify widgetSet
    (\cs -> H.foldrWithKey setWidgetStateJ cs encodedStatesFromBrowser)
  -- Find the callback.
  mcallback <- unSession $ lookupCallback callbackId
  case mcallback of
    Nothing ->
      -- Could not find callback; let's just fall back to doing nothing.
      return mempty
    Just callback ->
      -- Run the callback computation on an empty callback state.
      fmap snd $ unSession $ runCallbackT $ unWrapCallback callback