{-# LANGUAGE TemplateHaskell     #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE RecordWildCards     #-}
{-# LANGUAGE OverloadedStrings   #-}
{-# LANGUAGE TypeOperators       #-}
{-# LANGUAGE DeriveGeneric       #-}

-- | Generated from json response, now it's type safe, see the tests
module Speechmatics.JSON.PeekJob where

import           System.Exit        (exitFailure, exitSuccess)
import           System.IO          (stderr, hPutStrLn)
import qualified Data.ByteString.Lazy.Char8 as BSL
import           System.Environment (getArgs)
import           Control.Monad      (forM_, mzero, join)
import           Control.Applicative
import           Data.Aeson.AutoType.Alternative
import           Data.Aeson(decode, Value(..), FromJSON(..), ToJSON(..),
                            pairs, eitherDecode ,
                            (.:), (.:?), (.=), object)
import           Data.Monoid
import           Data.Text (Text)
import Data.Bifunctor
import qualified GHC.Generics

-- | Workaround for https://github.com/bos/aeson/issues/287.
o .:?? val = fmap join (o .:? val)

data Job = Job { 
    jobCheckWait :: (Maybe Integer),
    jobNotification :: Text,
    jobJobType :: Text,
    jobUrl :: Text,
    jobNextCheck :: Double,
    jobLang :: Text,
    jobJobStatus :: Text,
    jobName :: Text,
    jobCreatedAt :: Text,
    jobId :: Double,
    jobMeta :: (Maybe Value),
    jobUserId :: Double,
    jobDuration :: Double,
    jobTranscription :: Maybe Text
  } deriving (Show,Eq,GHC.Generics.Generic)


instance FromJSON Job where
  parseJSON (Object v) = Job <$> v .:?? "check_wait" <*> v .:   "notification" <*> v .:   "job_type" <*> v .:   "url" <*> v .:   "next_check" <*> v .:   "lang" <*> v .:   "job_status" <*> v .:   "name" <*> v .:   "created_at" <*> v .:   "id" <*> v .:?? "meta" <*> v .:   "user_id" <*> v .:   "duration" <*> v .:   "transcription"
  parseJSON _          = mzero


data TopLevel = TopLevel { 
    topLevelJob :: Job
  } deriving (Show,Eq,GHC.Generics.Generic)


instance FromJSON TopLevel where
  parseJSON (Object v) = TopLevel <$> v .:   "job"
  parseJSON _          = mzero

parse :: BSL.ByteString -> Either String Job
parse = (second topLevelJob)  -- get rid of toplevel
          . eitherDecode