content: {-# LANGUAGE ScopedTypeVariables #-}
  module PureScript.Ide.Command where
  
  import           Control.Monad
  import           Data.Aeson
  import           Data.Text (Text)
  import           Data.Maybe
  import           PureScript.Ide.Filter
  import           PureScript.Ide.Matcher
  import           PureScript.Ide.Types
  import           PureScript.Ide.CaseSplit
  
  data Command
      = Load { loadModules      :: [ModuleIdent]
             , loadDependencies :: [ModuleIdent]}
      | Type { typeSearch  :: DeclIdent
             , typeFilters :: [Filter]}
      | Complete { completeFilters :: [Filter]
                 , completeMatcher :: Matcher}
      | Pursuit { pursuitQuery      :: PursuitQuery
                , pursuitSearchType :: PursuitSearchType}
      | List {listType :: ListType}
      | CaseSplit {
        caseSplitLine :: Text
        , caseSplitBegin :: Int
        , caseSplitEnd :: Int
        , caseSplitAnnotations :: WildcardAnnotations
        , caseSplitType :: Type}
      | AddClause {
        addClauseLine :: Text
        , addClauseAnnotations :: WildcardAnnotations}
      | Cwd
      | Quit
  
  data ListType = LoadedModules | Imports FilePath | AvailableModules
  
  instance FromJSON ListType where
    parseJSON = withObject "ListType" $ \o -> do
      (listType' :: String) <- o .: "type"
      case listType' of
        "import" -> do
          fp <- o .: "file"
          return (Imports fp)
        "loadedModules" -> return LoadedModules
        "availableModules" -> return AvailableModules
        _ -> mzero
  
  instance FromJSON Command where
    parseJSON = withObject "command" $ \o -> do
      (command :: String) <- o .: "command"
      case command of
        "list" -> do
          listType' <- o .:? "params"
          return $ List (fromMaybe LoadedModules listType')
        "cwd"  -> return Cwd
        "quit" -> return Quit
        "load" -> do
          params <- o .: "params"
          mods <- params .:? "modules"
          deps <- params .:? "dependencies"
          return $ Load (fromMaybe [] mods) (fromMaybe [] deps)
        "type" -> do
          params <- o .: "params"
          search <- params .: "search"
          filters <- params .: "filters"
          return $ Type search filters
        "complete" -> do
          params <- o .: "params"
          filters <- params .:? "filters"
          matcher <- params .:? "matcher"
          return $ Complete (fromMaybe [] filters) (fromMaybe mempty matcher)
        "pursuit" -> do
          params <- o .: "params"
          query <- params .: "query"
          queryType <- params .: "type"
          return $ Pursuit query queryType
        "caseSplit" -> do
          params <- o .: "params"
          line <- params .: "line"
          begin <- params .: "begin"
          end <- params .: "end"
          annotations <- params .: "annotations"
          type' <- params .: "type"
          return $ CaseSplit line begin end (if annotations
                                             then explicitAnnotations
                                             else noAnnotations) type'
        "addClause" -> do
          params <- o .: "params"
          line <- params .: "line"
          annotations <- params .: "annotations"
          return $ AddClause line (if annotations
                                   then explicitAnnotations
                                   else noAnnotations)
        _ -> mzero
  
  