/**
 * Copyright (C) 2015 Laverna project Authors.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */
define(["underscore","q","sjcl"],function(r,e,t){"use strict";function n(){}return r.extend(n.prototype,{keys:[],hex:function(r){return t.codec.hex.fromBits(r)},toUpperCase:function(r){return r.toUpperCase().replace(/ /g,"").replace(/(.{8})/g,"$1 ").replace(/ $/,"")},sha256:function(r){return new e(r&&r.length?t.hash.sha256.hash(r):r)},getConfigs:function(r){return{mode:"ccm",iter:Number(r.encryptIter),ts:Number(r.encryptTag),ks:Number(r.encryptKeySize),salt:r.encryptSalt,v:1,adata:"",cipher:"aes"}},deriveKey:function(r){if(!Number(r.configs.encrypt))return{};var e,n={};return n.iter=Number(r.configs.encryptIter),n.salt=r.configs.encryptSalt,n=t.misc.cachedPbkdf2(r.password,n),e=n.key.slice(0,Number(r.configs.encryptKeySize)/32),this.keys={key:e,hexKey:t.codec.hex.fromBits(e)}},getKeys:function(r){return r.keys||this.keys},encrypt:function(r){if(!r.string||!Number(r.configs.encrypt))return r.string;var e=this.getConfigs(r.configs);return e.iv=r.iv,"string"!=typeof r.string&&(r.string=JSON.stringify(r.string)),r.string=t.encrypt(this.getKeys(r).key,r.string,e),r.string},decrypt:function(r){if(!r.string||!r.string.length||!Number(r.configs.encrypt))return r.string;try{r.string=t.decrypt(this.getKeys(r).key,r.string)}catch(e){return this.triggerDecryptError(e,r.string)}return r.string},decryptLegacy:function(e){if(!e.string||!e.string.length||!Number(e.configs.encrypt))return e.string;var n,s,i=this.getKeys(e),c=i.key.toString();try{n=r.unescape(e.string),s=JSON.parse(e.string)}catch(g){return e.string}r.size(s)<9&&(c=this.toUpperCase(i.hexKey),n=r.extend(this.getConfigs(e.configs),s),n=JSON.stringify(n));try{n=t.decrypt(c,n)}catch(g){return this.triggerDecryptError(g,n)}return n},triggerDecryptError:function(r,e){if(r.message.search("json decode")>-1&&!/"ct":"([^"]*)"./.test(e))return e;throw console.error("Decryption error",r,e),new Error(r.message)}}),n});