###
# Modern Albufeira Prolog Interpreter
#
# Warranty & Liability
# To the extent permitted by applicable law and unless explicitly
# otherwise agreed upon, XLOG Technologies AG makes no warranties
# regarding the provided information. XLOG Technologies AG assumes
# no liability that any problems might be solved with the information
# provided by XLOG Technologies AG.
#
# Rights & License
# All industrial property rights regarding the information - copyright
# and patent rights in particular - are the sole property of XLOG
# Technologies AG. If the company was not the originator of some
# excerpts, XLOG Technologies AG has at least obtained the right to
# reproduce, change and translate the information.
#
# Reproduction is restricted to the whole unaltered document. Reproduction
# of the information is only allowed for non-commercial uses. Selling,
# giving away or letting of the execution of the library is prohibited.
# The library can be distributed as part of your applications and libraries
# for execution provided this comment remains unchanged.
#
# Restrictions
# Only to be distributed with programs that add significant and primary
# functionality to the library. Not to be distributed with additional
# software intended to replace any components of the library.
#
# Trademarks
# Jekejeke is a registered trademark of XLOG Technologies AG.
##

from nova.core import (
    exec_build, exec_unify, set, make_check,
    check_atom, check_nonvar, copy_term, make_error, Compound)
import hashlib
import _hashlib


###
# digest_open(D): internal only
# The built-in succeeds in D with a new digest.
##
def test_digest_open(args):
    digest = hashlib.new('sha256')
    return exec_unify(args[0], digest)


###
# digest_update(D, B): internal only
# The built-in succeeds. As a side effect the digest D is updated by B.
##
def test_digest_update(args):
    alpha = exec_build(args[0])
    check_digest(alpha)
    beta = exec_build(args[1])
    check_atom(beta)
    buffer = beta.encode("latin1")
    alpha.update(buffer)
    return True


###
# Assure that the object is a digest.
#
# @param beta The object.
##
def check_digest(beta):
    if not isinstance(beta, _hashlib.HASH):
        check_nonvar(beta)
        beta = copy_term(beta)
        raise make_error(Compound("type_error", ["digest", beta]))


###
# digest_close(D, B): internal only
# The built-in succeeds in B with the result of the digest D.
##
def test_digest_close(args):
    alpha = exec_build(args[0])
    check_digest(alpha)
    buffer = alpha.digest()
    return exec_unify(args[1], buffer.decode("latin1"))


################################################################
# Sec Lib Init                                                 #
################################################################

def main():
    set("digest_open", 1, make_check(test_digest_open))
    set("digest_update", 2, make_check(test_digest_update))
    set("digest_close", 2, make_check(test_digest_close))
