@compiler >= 6

include "String.aes"
include "token.aes"

main contract Domains =
    record domain =
        { name : string, target: string, meta: string}
    record state =
        { owner        : address,
          domains     : map(address, map(string, domain)) }

    stateful entrypoint init() : state =
        { owner = Call.caller,
          domains = {} }

    function require_owner() =
        require(call.caller == state.owner, "only_owner_call_allowed")

    stateful entrypoint add_domain(account : address, name: string, target: string, meta: string) : bool =
        require_owner()
        require(Map.lookup(account, state.domains) != None, "Address not registered.")
        put(state{domains[account][name] = {name = name, target = target, meta = meta}})
        true

    entrypoint get_domains(account : address) : map(string, domain) =
        require_owner()
        require(Map.lookup(account, state.domains) != None, "Address not registered.")
        state.domains[account]

    stateful entrypoint delete_domain(name: string) =
        require_owner()
        let oldmap = Map.lookup_default(Call.caller, state.domains, {})
        let newmap = Map.delete(name, oldmap)
        put(state{domains[Call.caller] = newmap})

    stateful entrypoint get_domains(): map(string,string) =
        require_owner()
        Map.lookup_default(Call.caller, state.domains, {})

    stateful entrypoint add_domain_token(key: string, value: string) =
        require_owner()
        let oldmap = Map.lookup_default(Call.caller, state.domain_tokens, {})
        let newmap = oldmap{[key] = value}
        put(state{domain_tokens[Call.caller] = newmap})

    stateful entrypoint get_domain_token(key: string):  string =
        require_owner()
        let oldmap = Map.lookup_default(Call.caller, state.domain_tokens, {})
        Map.lookup_default(key, oldmap, "notfound")

    stateful entrypoint revoke_domain_token(key: string, value: string) =
        require_owner()
        let oldmap = Map.lookup_default(Call.caller, state.domain_tokens, {})
        let newmap = Map.delete(key, oldmap)
        put(state{domain_tokens[Call.caller] = newmap})
