var elliptic = require('elliptic');
var BN = require('bn.js');
module.exports = ECDH;

function ECDH(curve, crypto) {
	elliptic.rand = crypto.randomBytes;
	this.curve = new elliptic.ec(curve);
	this.keys = void 0;
}
ECDH.prototype.generateKeys = function (enc, format) {
	this.keys = this.curve.genKeyPair();
	return this.getPublicKey(enc, format);
};

ECDH.prototype.computeSecret = function (other, inenc, enc) {
	inenc = inenc || 'utf8';
	if (!Buffer.isBuffer(other)) {
		other = new Buffer(other, inenc);
	}
	other = new BN(other);
	other = other.toString(16);
	var otherPub = this.curve.keyPair(other, 'hex').getPublic();
	var out = otherPub.mul(this.keys.getPrivate()).getX();
	return returnValue(out, enc);
};
ECDH.prototype.getPublicKey = function (enc, format) {
	var key = this.keys.getPublic(format === 'compressed', true);
	if (format === 'hybrid') {
		if (key[key.length - 1] % 2) {
			key[0] = 7;
		} else {
			key [0] = 6;
		}
	}
	return returnValue(key, enc);
};
ECDH.prototype.getPrivateKey = function (enc) {
	return returnValue(this.keys.getPrivate(), enc);
};

ECDH.prototype.setPublicKey = function (pub, enc) {
	enc = enc || 'utf8';
	if (!Buffer.isBuffer(pub)) {
		pub = new Buffer(pub, enc);
	}
	var pkey = new BN(pub);
	pkey = pkey.toArray();
	this.keys._importPublicHex(pkey);
};
ECDH.prototype.setPrivateKey = function (priv, enc) {
	enc = enc || 'utf8';
	if (!Buffer.isBuffer(priv)) {
		priv = new Buffer(priv, enc);
	}
	var _priv = new BN(priv);
	_priv = _priv.toString(16);
	this.keys._importPrivate(_priv);
};
function returnValue(bn, enc) {
	if (!Array.isArray(bn)) {
		bn = bn.toArray();
	}
	var buf = new Buffer(bn);
	if (!enc) {
		return buf;
	} else {
		return buf.toString(enc);
	}
}