### codetube
    Copyright (C) 2011 payload payload@lavabit.com
    Copyright (C) 2011 dodo dodo.the.last@gmail.com

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>
###

util = require('util')
http = require('http')
crypto = require('crypto')
BufferStream = require('bufferstream')
config = null # circular dependency

EMAIL_MATCH =  /(<{0,1}\s*((([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,})))\s*>{0,1})/
SPACE_TRIM = /(\s+)/g

module.exports = helper =
    hash: (type) ->
        hash: (msg) ->
            msg = ""+msg if typeof msg isnt 'string'
            hashsum = crypto.createHash(type)
            hashsum.update(msg)
            hashsum.digest('hex')

    foldl: (object, array, worker) ->
        object = worker(object, value) for value in array
        object

    sum: (array) ->
        res = 0
        res += value for value in array
        res

    obj_merge: (objs...) ->
        objs = objs[0] if Array.isArray(objs[0])
        ret = {}
        for obj in objs
            ret[k] = v for k, v of obj
        ret

    obj_deep_merge: (objs...) ->
        objs = objs[0] if Array.isArray(objs[0])
        ret = {}
        for obj in objs
            for k, v of obj
                if typeof(v) == 'object' and not Array.isArray(v)
                    ret[k] = helper.obj_deep_merge(ret[k] or {}, v)
                else
                    ret[k] = v
        ret

    obj_overwrite: (victim, objs...) ->
        objs = objs[0] if Array.isArray(objs[0])
        for obj in objs
            victim[k] = v for k, v of obj
        victim

    debug_log: (args...) ->
        config or= require('./config') # circular dependency
        return unless config.debug.enable
        args.push (new Error).stack.split('\n')[2]
        console.log.apply console, args

    errsafe: (func) ->
        (err, args...) ->
            return console.log(42, err) if err # XXX debug_log(err) if err
            func(args...)

    request: (port, method, path, data..., opts, callback) ->
        config or= require('./config') # circular dependency
        host = config.worker.address
        req = http.request {port, method, path, host}, (res) ->
            buffer = new BufferStream()
            res.pipe(buffer)
            return callback(null, buffer) if opts.stream
            buffer.on 'end', () -> callback(null, buffer)
        req.on 'error', (err) -> callback(err)
        data = (JSON.stringify(dat) for dat in data) if opts.json
        for dat in data
            #dat = util.inspect(dat, styles:no) unless dat is 'string' # FIXME
            req.write(new Buffer(dat, 'utf8')) if dat?.length
        req.end()

    parse_author: (author) ->
        email = author.match(EMAIL_MATCH)
        if email
            name = author.replace(email[0], "").trim().replace(SPACE_TRIM, " ")
            email = email[2]
            name = email if not name
        else
            name = author.replace(SPACE_TRIM, " ")
        return name:name, email:email

