/**
 * Copyright 2016 the WHATAP project authors. All rights reserved.
 * Use of this source code is governed by a license that
 * can be found in the LICENSE file.
 */

var crypto      = require('crypto'),
    DataOutputX = require('./../io/data-outputx');

var Cypher = function(cypherKey,  xor_key) {
    xor_key = xor_key || 0;

    this.BLOCK = require('./../conf/configure').cypher_level / 8;
    this.key = cypherKey = Cypher.padding(cypherKey);
    this.enc = crypto.createCipheriv("AES-128-ECB", cypherKey, '');

    this.dec = crypto.createDecipheriv("AES-128-ECB", cypherKey, '');
    this.dec.setAutoPadding(false);

    this.xor_key = DataOutputX.toBytes(xor_key, 4);
};

Cypher.padding = function( src ){
    if(src.length === 16){
        return src;
    }
    var dest = Buffer.alloc(16 , 0);
    if(src.length > 16){
        src.copy(dest, 0 , 0, dest.length);
    }else{
        src.copy(dest, 0 , 0, src.length);
    }
    return dest;
};
Cypher.prototype.encryptBlock = function(data){
    try{
        if(this.BLOCK === 0){
            return data;
        }
        var ret = Buffer.concat([this.enc.update(data), this.enc.final()]);
        this.enc = crypto.createCipheriv( "AES-128-ECB", this.key, '');
        return ret;
    }catch(e){
        console.error(e);
    }
};
Cypher.prototype.hide = function(b){
    if( this.BLOCK === 0){
        return b;
    }
    for( var i = 0 , j = 0 ; i< b.length ; i++, j = (j+1) % this.xor_key.length){
        b[i] ^= this.xor_key[j];
    }
    return b;
};
Cypher.prototype.encrypt = function(data){
    this.enc = crypto.createCipheriv("AES-128-ECB", this.key, '');
    var len = data.length;
    var remainder = len % 16;
    var buf = null;
    if(remainder === 0 ){
        buf = data;
    } else {
        buf = Buffer.alloc((Math.floor(len / 16) +1) * 16 , 0);
        DataOutputX.set(buf, 0, data );
    }
    try {
        if(data.length <= 16) {
            return Buffer.concat([this.enc.update(buf)]);
        } else {
            return Buffer.concat([this.enc.update(buf), this.enc.final()]);
        }
    } catch(e) {
    }
    return null;
};
Cypher.prototype.decrypt = function(data){
    this.dec = crypto.createDecipheriv( "AES-128-ECB", this.key, '');
    this.dec.setAutoPadding(false);

    try {
        var b = this.dec.update(data);
        var f = this.dec.final();
        return Buffer.concat([b, f]);
    }catch(e){
    }
    return null;
};

module.exports = Cypher;