var sign = require('./sign');
var verify = require('./verify');
var stream = require('stream');
var inherits = require('inherits');
var _algos = require('./algos');
var algos = {};
Object.keys(_algos).forEach(function (key) {
	algos[key] = algos[key.toLowerCase()] = _algos[key];
});
'use strict';
module.exports = function (exports, crypto) {
	exports.createSign = exports.Sign = createSign;
	function createSign(algorithm) {

		return new Sign(algorithm, crypto);
	}
	exports.createVerify = exports.Verify = createVerify;
	function createVerify(algorithm) {
		return new Verify(algorithm, crypto);
	}
};
inherits(Sign, stream.Writable);
function Sign(algorithm, crypto) {
	stream.Writable.call(this);
	var data = algos[algorithm];
	if (!data) {
		throw new Error('Unknown message digest');
	}
	this._hashType = data.hash;
	this._hash = crypto.createHash(data.hash);
	this._tag = data.id;
	this._crypto = crypto;
}
Sign.prototype._write = function _write(data, _, done) {
	this._hash.update(data);
	done();
};
Sign.prototype.update = function update(data) {
	this.write(data);
	return this;
};

Sign.prototype.sign = function signMethod(key, enc) {
	this.end();
	var hash = this._hash.digest();
	var sig = sign(Buffer.concat([this._tag, hash]), key, this._hashType, this._crypto);
	if (enc) {
		sig = sig.toString(enc);
	}
	return sig;
};

inherits(Verify, stream.Writable);
function Verify(algorithm, crypto) {
	stream.Writable.call(this);
	var data = algos[algorithm];
	if (!data) {
		throw new Error('Unknown message digest');
	}
	this._hash = crypto.createHash(data.hash);
	this._tag = data.id;
}
Verify.prototype._write = function _write(data, _, done) {
	this._hash.update(data);
	done();
};
Verify.prototype.update = function update(data) {
	this.write(data);
	return this;
};

Verify.prototype.verify = function verifyMethod(key, sig, enc) {
	this.end();
	var hash = this._hash.digest();
	if (!Buffer.isBuffer(sig)) {
		sig = new Buffer(sig, enc);
	}
	return verify(sig, Buffer.concat([this._tag, hash]), key);
};