module Data exposing (..)

import Time exposing (Posix)
import Json.Decode as JD exposing (Value, Decoder)
import Json.Decode.Pipeline exposing (required, optional)
import Json.Encode as JE
import Iso8601

type alias Id = String

decodeId : Decoder Id
decodeId = JD.string

encodeId : Id -> Value
encodeId = JE.string

type alias Interview =
    { id: Id
    , database: String
    , created: Posix
    , modified: Posix
    , deleted: Bool
    , time: Posix
    , location: String
    , interviewer: String
    }

decodeInterview : Decoder Interview
decodeInterview =
    JD.succeed Interview
        |> required "id" decodeId
        |> required "database" JD.string
        |> required "created" Iso8601.decoder
        |> required "modified" Iso8601.decoder
        |> required "deleted" JD.bool
        |> required "time" Iso8601.decoder
        |> required "location" JD.string
        |> required "interviewer" JD.string

type alias Person =
    { id: Id
    , database: String
    , created: Posix
    , modified: Posix
    , deleted: Bool
    , interview: Maybe Id
    , name: Maybe String
    , altName: String
    , contact: Maybe String
    , role: String
    , attributes: List Attribute
    }

decodePerson : Decoder Person
decodePerson =
    JD.succeed Person
        |> required "id" decodeId
        |> required "database" JD.string
        |> required "created" Iso8601.decoder
        |> required "modified" Iso8601.decoder
        |> required "deleted" JD.bool
        |> optional "interview" (JD.nullable decodeId) Nothing
        |> optional "name" (JD.nullable JD.string) Nothing
        |> required "altName" JD.string
        |> optional "contact" (JD.nullable JD.string) Nothing
        |> required "role" JD.string
        |> required "attributes" (JD.list decodeAttribute)

type alias Attribute =
    { key: String
    , created: Posix
    , modified: Posix
    , entries: List AttributeEntry
    , entry: AttributeEntry
    }

decodeAttribute : Decoder Attribute
decodeAttribute =
    JD.succeed Attribute
        |> required "key" JD.string
        |> required "created" Iso8601.decoder
        |> required "modified" Iso8601.decoder
        |> required "entries" (JD.list decodeAttributeEntry)
        |> required "entry" decodeAttributeEntry

type alias AttributeEntry =
    { date: Posix
    , value: Value
    }

decodeAttributeEntry : Decoder AttributeEntry
decodeAttributeEntry =
    JD.succeed AttributeEntry
        |> required "date" Iso8601.decoder
        |> required "value" JD.value

type alias File =
    { id: Id
    , database: String
    , created: Posix
    , modified: Posix
    , deleted: Bool
    , person: Id
    , parent: Maybe Id
    , name: String
    , mime: String
    , confidential: Bool
    , entries: List FileEntry
    , entry: Maybe FileEntry
    }

decodeFile : Decoder File
decodeFile =
    JD.succeed File
        |> required "id" decodeId
        |> required "database" JD.string
        |> required "created" Iso8601.decoder
        |> required "modified" Iso8601.decoder
        |> required "deleted" JD.bool
        |> required "person" decodeId
        |> optional "parent" (JD.nullable decodeId) Nothing
        |> required "name" JD.string
        |> required "mime" JD.string
        |> required "confidential" JD.bool
        |> required "entries" (JD.list decodeFileEntry)
        |> optional "entry" (JD.nullable decodeFileEntry) Nothing

type alias FileEntry =
    { date: Posix
    , exists: Bool -- true if the file is available in the file system
    }

decodeFileEntry : Decoder FileEntry
decodeFileEntry =
    JD.succeed FileEntry
        |> required "date" Iso8601.decoder
        |> required "exists" JD.bool
