# -*- coding: utf-8 -*-
'''
.. versionadded:: Helium

Provides access to randomness generators.
'''

# Import python libs
import base64
import hashlib
import os

# Import salt libs
from salt.exceptions import SaltInvocationError

# Define the module's virtual name
__virtualname__ = 'random'


def __virtual__():
    '''
    Confirm this module is on a Debian based system
    '''
    return __virtualname__


def encode(value, encoder='sha256'):
    '''
    .. versionadded:: Helium

    Encodes a value with the specified encoder.

    value
        The value to be encoded.

    encoder : sha256
        The encoder to use. May be any valid algorithm supported by hashlib or
        ``base64``.

    CLI Example:

    .. code-block:: bash

        salt '*' random.encode 'I am a string' md5
    '''
    if encoder == 'base64':
        out = base64.b64encode(value)
    elif encoder in hashlib.algorithms:
        hasher = hashlib.new(encoder)
        hasher.update(value)
        out = hasher.hexdigest()
    else:
        raise SaltInvocationError('You must specify a valid encoder.')

    return out


def urandom(length=256, encoder=None):
    '''
    .. versionadded:: Helium

    Returns a random string of the specified length, optionally encoded. The
    truncation takes place prior to encoding so final output may be larger or
    smaller according to the encoder output.

    length : 256
        Any valid number of bytes.

    encoder : None
        An optional encoder. May be any valid algorithm supported by haslib
        or ``base64``.

    CLI Example:

    .. code-block:: bash

        salt '*' random.get 128 sha512
    '''

    rand = os.urandom(length)

    if encoder is not None:
        rand = encode(rand, encoder)

    return rand

# -*- coding: utf-8 -*-
'''
.. versionadded:: Helium

Provides access to randomness generators.
'''
# Import python libs
import hashlib

# Import salt libs
import salt.utils.pycrypto
from salt.exceptions import SaltInvocationError

# Define the module's virtual name
__virtualname__ = 'random'


def __virtual__():
    '''
    Confirm this module is on a Debian based system
    '''
    return __virtualname__


def hash(value, algorithm='sha512'):
    '''
    .. versionadded:: Helium

    Encodes a value with the specified encoder.

    value
        The value to be hashed.

    algorithm : sha512
        The algorithm to use. May be any valid algorithm supported by
        hashlib.

    CLI Example:

    .. code-block:: bash

        salt '*' random.hash 'I am a string' md5
    '''
    if algorithm in hashlib.algorithms:
        hasher = hashlib.new(algorithm)
        hasher.update(value)
        out = hasher.hexdigest()
    else:
        raise SaltInvocationError('You must specify a valid algorithm.')

    return out


def str_encode(value, encoder = 'base64'):
    '''
    .. versionadded:: Helium

    value
        The value to be encoded.

    encoder : base64
        The encoder to use on the subsequent string.

    CLI Example:

    .. code-block:: bash

        salt '*' random.str_encode 'I am a new string' base64
    '''
    try:
        out = value.encode(encoder)
    except LookupError:
        raise SaltInvocationError('You must specify a valid encoder')
    except AttributeError:
        raise SaltInvocationError('Value must be an encode-able string')

    return out
        

def get_str(length=20):
    '''
    .. versionadded:: Helium

    Returns a random string of the specified length.

    length : 20
        Any valid number of bytes.

    CLI Example:

    .. code-block:: bash

        salt '*' random.get 128
    '''

    return salt.utils.pycrypto.secure_password(length)


def salted_hash(crypt_salt=None, crypt_value=None, algorithm='sha512'):
    '''
    Generates a salted hash.

    crypt_salt : None
        Salt to be used in the generation of the hash. If one is not
        provided, a random salt will be generated.

    crypt_value : None
        Value to be salted and hashed. If one is not provided, a random
        value will be generated.

    algorithm : sha512
        Hash algorithm to use.

    CLI Example:

    .. code-block:: bash

        salt '*' 'My5alT' 'I am a value to be hashed' md5
    '''
    return salt.utils.pycrypto.gen_hash(crypt_salt, crypt_value, algorithm)

Change mod_random to use pycrypto backend.