{-# LANGUAGE OverloadedStrings, TemplateHaskell #-}
module Data.Library.UUIRI
( UUIRI (..)
, iri
, uuid
, toUUIRI
, fromUUIRI
, isRelative
, isAbsolute
, extension
, domain
, protocol
, dirs
)
where

import Data.Text (Text)
import Data.Library.IRI (IRI, fromIRI)
import qualified Data.Library.IRI as IRI
import Data.Aeson (ToJSON(toJSON), FromJSON(parseJSON), object, (.=), (.:), Value(Object))
import Control.Applicative ((<$>), (<*>))
import Control.Monad (mzero)
import Data.SafeCopy (deriveSafeCopy, base)
import Data.Indexation.UUID (UUID)

newtype UUIRI = UUIRI (UUID, IRI) 

instance Eq UUIRI where
    uuiri1 == uuiri2 = uuid uuiri1 == uuid uuiri2

instance ToJSON UUIRI where
    toJSON (UUIRI (u,i)) = object [ "uuid" .= u, "iri" .= fromIRI i ]

instance FromJSON UUIRI where
    parseJSON (Object v) = toUUIRI <$> v .: "uuid" <*> v .: "iri"
    parseJSON _          = mzero

-- | returns the IRI part of the UUIRI
iri :: UUIRI -> IRI
iri (UUIRI tuple) = snd tuple

-- | returns the UUID part of the UUIRI
uuid :: UUIRI -> UUID
uuid (UUIRI tuple) = fst tuple

-- | a constructor for UUIRIs
toUUIRI :: UUID -> Text -> UUIRI
toUUIRI u t = UUIRI (u, IRI.toIRI t)

-- | returns the UUIRI tuple with the IRI translated to Text
fromUUIRI :: UUIRI -> (UUID, Text)
fromUUIRI (UUIRI (u,iri')) = (u, IRI.fromIRI iri')

-- | is the IRI part of the UUIRI a relative IRI ?
isRelative :: UUIRI -> Bool
isRelative = IRI.isRelative . iri

-- | is the IRI part of the UUIRI an absolute IRI ?
isAbsolute :: UUIRI -> Bool
isAbsolute = IRI.isAbsolute . iri

-- | returns the IRI extension of a given UUIRI 
extension :: UUIRI -> Maybe Text
extension = IRI.extension . iri

-- | returns the IRI domain of a given UUIRI 
domain :: UUIRI -> Maybe Text
domain = IRI.domain . iri

-- | returns the IRI protocol of a given UUIRI 
protocol :: UUIRI -> Maybe Text
protocol = IRI.protocol . iri

-- | returns the IRI directories of a given UUIRI 
dirs :: UUIRI -> [Text]
dirs = IRI.dirs . iri

$(deriveSafeCopy 0 'base ''UUIRI) -- from Data.SafeCopy