/*
    PIP - Platform Independent Primitives
    Base class for ethernet utils
    Ivan Pelipenko peri4ko@yandex.ru

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser 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 Lesser General Public License for more details.

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

#include "piethutilbase.h"

#include "pitranslator.h"
#ifdef PIP_CRYPT
#  include "picrypt.h"
#endif

/** \class PIEthUtilBase
 * \brief Base class for ethernet utils
 *
 * \section PIEthUtilBase_synopsis Synopsis
 * %PIEthUtilBase provides crypt layer for derived classes:
 * \a PIStreamPacker and \a PIBroadcast. All input and output
 * (sended and received) data can be decrypted/encrypted by this layer.
 *
 * By default crypt layer is disabled.
 *
 * You can separetely enable it and set ready-to-use
 * key by \a setCryptEnabled() and \a setCryptKey(). Or you can
 * use \a createCryptKey() to generate key from your passphrase
 * and automatic enable crypt layer.
 *
 * \note To use crypt layer, PIP should be built with crypt module,
 * otherwise your in/out data will be lost.
 *
 * You can use this class as base for your own classes. Use \a cryptData()
 * and \a decryptData() when send and receive your data.
 *
 */


PIEthUtilBase::PIEthUtilBase() {
	_crypt = false;
}


PIEthUtilBase::~PIEthUtilBase() {}


void PIEthUtilBase::setCryptEnabled(bool on) {
	_crypt = on;
}


void PIEthUtilBase::cryptEnable() {
	setCryptEnabled(true);
}


void PIEthUtilBase::cryptDisable() {
	setCryptEnabled(false);
}


bool PIEthUtilBase::isCryptEnabled() const {
	return _crypt;
}


void PIEthUtilBase::setCryptKey(const PIByteArray & k) {
	_key = k;
	setCryptEnabled(true);
}


void PIEthUtilBase::createCryptKey(const PIString & k) {
#ifdef PIP_CRYPT
	_key = PICrypt::hash("sodium_bug");
	_key = PICrypt::hash(k);
#else
	piCout << "[PIEthUtilBase]"
		   << "PICrypt wasn`t built!"_tr("PIEthUtilBase");
#endif
	_crypt = true;
}


PIByteArray PIEthUtilBase::cryptKey() const {
	return _key;
}


PIByteArray PIEthUtilBase::cryptData(const PIByteArray & data) {
	if (!_crypt) return data;
	return
#ifdef PIP_CRYPT
		PICrypt::crypt(data, _key);
#else
		PIByteArray();
#endif
}


PIByteArray PIEthUtilBase::decryptData(const PIByteArray & data) {
	if (!_crypt) return data;
#ifdef PIP_CRYPT
	bool ok         = false;
	PIByteArray ret = PICrypt::decrypt(data, _key, &ok);
	if (!ok) return PIByteArray();
	return ret;
#else
	return PIByteArray();
#endif
}

size_t PIEthUtilBase::cryptSizeAddition() {
#ifdef PIP_CRYPT
	return PICrypt::sizeCrypt();
#else
	return 0;
#endif
}
