Add a job to the queue.

    The 'timespec' follows the format documented in the
    at(1) manpage.

    CLI Example:

    .. code-block:: bash

        salt '*' at.at <timespec> <cmd> [tag=<tag>] [runas=<user>]
        salt '*' at.at 12:05am '/sbin/reboot' tag=reboot
        salt '*' at.at '3:05am +3 days' 'bin/myscript' tag=nightly runas=jim

def at(*args, **kwargs):  # pylint: disable=C0103
    '''
    Add a job to the queue.

    The 'timespec' follows the format documented in the
    at(1) manpage.

    CLI Example:

    .. code-block:: bash

        salt '*' at.at <timespec> <cmd> [tag=<tag>] [runas=<user>]
        salt '*' at.at 12:05am '/sbin/reboot' tag=reboot
        salt '*' at.at '3:05am +3 days' 'bin/myscript' tag=nightly runas=jim
    '''

    # check args
    if len(args) < 2:
        return {'jobs': []}

    # build job
    if 'tag' in kwargs:
        stdin = '### SALT: {0}\n{1}'.format(kwargs['tag'], ' '.join(args[1:]))
    else:
        stdin = ' '.join(args[1:])

    cmd_kwargs = {'stdin': stdin, 'python_shell': False}
    if 'runas' in kwargs:
        cmd_kwargs['runas'] = kwargs['runas']
    res = __salt__['cmd.run_all']('at "{timespec}"'.format(
        timespec=args[0]
    ), **cmd_kwargs)

    # verify job creation
    if res['retcode'] > 0:
        if 'bad time specification' in res['stderr']:
            return {'jobs': [], 'error': 'invalid timespec'}
        return {'jobs': [], 'error': res['stderr']}
    else:
        jobid = res['stderr'].splitlines()[1]
        jobid = six.text_type(jobid.split()[1])
        return atq(jobid)