/*
* Copyright 2008, 2009, 2014 Free Software Foundation, Inc.
* Copyright 2014 Range Networks, Inc.
*
* This software is distributed under the terms of the GNU Affero Public License.
* See the COPYING file in the main directory for details.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.

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

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

*/


#ifndef BITVECTORS_H
#define BITVECTORS_H

#include "Vector.h"
#include <stdint.h>
#include <stdio.h>


class BitVector;
class SoftVector;




/** Shift-register (LFSR) generator. */
class Generator {

	private:

	uint64_t mCoeff;	///< polynomial coefficients. LSB is zero exponent.
	uint64_t mState;	///< shift register state. LSB is most recent.
	uint64_t mMask;		///< mask for reading state
	unsigned mLen;		///< number of bits used in shift register
	unsigned mLen_1;	///< mLen - 1

	public:

	Generator(uint64_t wCoeff, unsigned wLen)
		:mCoeff(wCoeff),mState(0),
		mMask((1ULL<<wLen)-1),
		mLen(wLen),mLen_1(wLen-1)
	{ assert(wLen<64); }

	void clear() { mState=0; }

	/**@name Accessors */
	//@{
	uint64_t state() const { return mState & mMask; }
	unsigned size() const { return mLen; }
	//@}

	/**
		Calculate one bit of a syndrome.
		This is in the .h for inlining.
	*/
	void syndromeShift(unsigned inBit)
	{
		const unsigned fb = (mState>>(mLen_1)) & 0x01;
		mState = (mState<<1) ^ (inBit & 0x01);
		if (fb) mState ^= mCoeff;
	}

	/**
		Update the generator state by one cycle.
		This is in the .h for inlining.
	*/
	void encoderShift(unsigned inBit)
	{
		const unsigned fb = ((mState>>(mLen_1)) ^ inBit) & 0x01;
		mState <<= 1;
		if (fb) mState ^= mCoeff;
	}


};




/** Parity (CRC-type) generator and checker based on a Generator. */
class Parity : public Generator {

	protected:

	unsigned mCodewordSize;

	public:

	Parity(uint64_t wCoefficients, unsigned wParitySize, unsigned wCodewordSize)
		:Generator(wCoefficients, wParitySize),
		mCodewordSize(wCodewordSize)
	{ }

	/** Compute the parity word and write it into the target segment.  */
	void writeParityWord(const BitVector& data, BitVector& parityWordTarget, bool invert=true);

	/** Compute the syndrome of a received sequence. */
	uint64_t syndrome(const BitVector& receivedCodeword);
};


// (pat) Nov 2013.  I rationalized the behavior of BitVector and added assertions to core dump code
// that relied on the bad aspects of the original behavior.  See comments at VectorBase.
class BitVector : public VectorBase<char>
{
	public:
	/**@name Constructors. */
	//@{

	/**@name Casts of Vector constructors. */
	BitVector(VectorDataType wData, char* wStart, char* wEnd) : VectorBase<char>(wData, wStart, wEnd) {}

	// The one and only copy-constructor.
	BitVector(const BitVector&other) : VectorBase<char>() {
		VECTORDEBUG("BitVector(%p)",(void*)&other);
		if (other.getData()) {
			this->clone(other);
		} else {
			this->makeAlias(other);
		}
	}

	// (pat) Removed default value for len and added 'explicit'.  Please do not remove 'explicit';
	// it prevents auto-conversion of int to BitVector in constructors.
	// Previous code was often ambiguous, especially for L3Frame and descendent constructors, leading to latent bugs.
	explicit BitVector(size_t len) { this->vInit(len); }
	BitVector() { this->vInit(0); }

	/** Build a BitVector by concatenation. */
	BitVector(const BitVector& other1, const BitVector& other2) : VectorBase<char>()
	{
		assert(this->getData() == 0);
		this->vConcat(other1,other2);
	}

	/** Construct from a string of "0" and "1". */
	// (pat) Characters that are not '0' or '1' map to '0'.
	BitVector(const char* valString);
	//@}

	/**@name Casts and overrides of Vector operators. */
	//@{
	// (pat) Please DO NOT add a const anywhere in this method.  Use cloneSegment instead.
	BitVector segment(size_t start, size_t span)
	{
		char* wStart = this->begin() + start;
		char* wEnd = wStart + span;
		assert(wEnd<=this->end());
#if BITVECTOR_REFCNTS
		return BitVector(mData,wStart,wEnd);
#else
		return BitVector(NULL,wStart,wEnd);
#endif
	}

	// (pat) Historically the BitVector segment method had const and non-const versions with different behavior.
	// I changed the name of the const version to cloneSegment and replaced all uses throughout OpenBTS.
	const BitVector cloneSegment(size_t start, size_t span) const
	{
		BitVector seg = const_cast<BitVector*>(this)->segment(start,span);
		// (pat) We are depending on the Return Value Optimization not to invoke the copy-constructor on the result,
		// which would result in its immediate destruction while we are still using it.
		BitVector result;
		result.clone(seg);
		return result;
	}

	BitVector alias() const {
		return const_cast<BitVector*>(this)->segment(0,size());
	}

	BitVector head(size_t span) { return segment(0,span); }
	BitVector tail(size_t start) { return segment(start,size()-start); }

	// (pat) Please do NOT put the const version of head and tail back in, because historically they were messed up.
	// Use cloneSegment instead.
	//const BitVector head(size_t span) const { return segment(0,span); }
	//const BitVector tail(size_t start) const { return segment(start,size()-start); }
	//@}


	void zero() { fill(0); }

	/**@name FEC operations. */
	//@{
	/** Calculate the syndrome of the vector with the given Generator. */
	uint64_t syndrome(Generator& gen) const;
	/** Calculate the parity word for the vector with the given Generator. */
	uint64_t parity(Generator& gen) const;
	//@}


	/** Invert 0<->1. */
	void invert();

	/**@name Byte-wise operations. */
	//@{
	/** Reverse an 8-bit vector. */
	void reverse8();
	/** Reverse groups of 8 within the vector (byte reversal). */
	void LSB8MSB();
	//@}

	/**@name Serialization and deserialization. */
	//@{
	uint64_t peekField(size_t readIndex, unsigned length) const;
	uint64_t peekFieldReversed(size_t readIndex, unsigned length) const;
	uint64_t readField(size_t& readIndex, unsigned length) const;
	uint64_t readFieldReversed(size_t& readIndex, unsigned length) const;
	void fillField(size_t writeIndex, uint64_t value, unsigned length);
	void fillFieldReversed(size_t writeIndex, uint64_t value, unsigned length);
	void writeField(size_t& writeIndex, uint64_t value, unsigned length);
	void writeFieldReversed(size_t& writeIndex, uint64_t value, unsigned length);
	void write0(size_t& writeIndex) { writeField(writeIndex,0,1); }
	void write1(size_t& writeIndex) { writeField(writeIndex,1,1); }

	//@}

	/** Sum of bits. */
	unsigned sum() const;

	/** Reorder bits, dest[i] = this[map[i]]. */
	void map(const unsigned *map, size_t mapSize, BitVector& dest) const;

	/** Reorder bits, dest[map[i]] = this[i]. */
	void unmap(const unsigned *map, size_t mapSize, BitVector& dest) const;

	/** Pack into a char array. */
	void pack(unsigned char*) const;
	// Same as pack but return a string.
	std::string packToString() const;

	/** Unpack from a char array. */
	void unpack(const unsigned char*);

	/** Make a hexdump string. */
	void hex(std::ostream&) const;
	std::string hexstr() const;

	/** Unpack from a hexdump string.
	*  @returns true on success, false on error. */
	bool unhex(const char*);

	// For this method, 'other' should have been run through the copy-constructor already
	// (unless it was newly created, ie foo.dup(L2Frame(...)), in which case we are screwed anyway)
	// so the call to makeAlias is redundant.
	// This only works if other is already an alias.
	void dup(BitVector other) { assert(!this->getData()); makeAlias(other); assert(this->mStart == other.mStart); }
	void dup(BitVector &other) { makeAlias(other); assert(this->mStart == other.mStart); }

#if 0
	void operator=(const BitVector& other) {
		printf("BitVector::operator=\n");
		assert(0);
		//this->dup(other);
	}
#endif

    bool operator==(const BitVector &other) const;

	/** Copy to dst, not including those indexed in puncture. */
	void copyPunctured(BitVector &dst, const unsigned *puncture, const size_t plth);

	/** Index a single bit. */
	// (pat) Cant have too many ways to do this, I guess.
	bool bit(size_t index) const
	{
		// We put this code in .h for fast inlining.
		const char *dp = this->begin()+index;
		assert(dp<this->end());
		return (*dp) & 0x01;
	}

	char& operator[](size_t index)
	{
		assert(this->mStart+index<this->mEnd);
		return this->mStart[index];
	}

	const char& operator[](size_t index) const
	{
		assert(this->mStart+index<this->mEnd);
		return this->mStart[index];
	}

	/** Set a bit */
	void settfb(size_t index, int value)
	{
		char *dp = this->mStart+index;
		assert(dp<this->mEnd);
		*dp = value;
	}

	typedef char* iterator;
	typedef const char* const_iterator;
};

// (pat) BitVector2 was an intermediate step in fixing BitVector but is no longer needed.
#define BitVector2 BitVector


std::ostream& operator<<(std::ostream&, const BitVector&);






/**
  The SoftVector class is used to represent a soft-decision signal.
  Values 0..1 represent probabilities that a bit is "true".
 */
class SoftVector: public Vector<float> {

	public:

	/** Build a SoftVector of a given length. */
	SoftVector(size_t wSize=0):Vector<float>(wSize) {}

	/** Construct a SoftVector from a C string of "0", "1", and "X". */
	SoftVector(const char* valString);

	/** Construct a SoftVector from a BitVector. */
	SoftVector(const BitVector& source);

	/**
		Wrap a SoftVector around a block of floats.
		The block will be delete[]ed upon desctuction.
	*/
	SoftVector(float *wData, unsigned length)
		:Vector<float>(wData,length)
	{}

	SoftVector(float* wData, float* wStart, float* wEnd)
		:Vector<float>(wData,wStart,wEnd)
	{ }

	/**
		Casting from a Vector<float>.
		Note that this is NOT pass-by-reference.
	*/
	SoftVector(Vector<float> source)
		:Vector<float>(source)
	{}


	/**@name Casts and overrides of Vector operators. */
	//@{
	SoftVector segment(size_t start, size_t span)
	{
		float* wStart = mStart + start;
		float* wEnd = wStart + span;
		assert(wEnd<=mEnd);
		return SoftVector(NULL,wStart,wEnd);
	}

	SoftVector alias()
		{ return segment(0,size()); }

	const SoftVector segment(size_t start, size_t span) const
		{ return (SoftVector)(Vector<float>::segment(start,span)); }

	SoftVector head(size_t span) { return segment(0,span); }
	const SoftVector head(size_t span) const { return segment(0,span); }
	SoftVector tail(size_t start) { return segment(start,size()-start); }
	const SoftVector tail(size_t start) const { return segment(start,size()-start); }
	//@}

	// (pat) How good is the SoftVector in the sense of the bits being solid?
	// Result of 1 is perfect and 0 means all the bits were 0.5
	// If plow is non-NULL, also return the lowest energy bit.
	float getEnergy(float *low=0) const;
	float getSNR() const;

	/** Fill with "unknown" values. */
	void unknown() { fill(0.5F); }

	/** Return a hard bit value from a given index by slicing. */
	bool bit(size_t index) const
	{
		const float *dp = mStart+index;
		assert(dp<mEnd);
		return (*dp)>0.5F;
	}

	/** Slice the whole signal into bits. */
	BitVector sliced() const;

	/** Copy to dst, adding in 0.5 for those indexed in puncture. */
	void copyUnPunctured(SoftVector &dst, const unsigned *puncture, const size_t plth);

	/** Return a soft bit. */
	float softbit(size_t index) const
	{
		const float *dp = mStart+index;
		assert(dp<mEnd);
		return *dp;
	}

	/** Set a soft bit */
	void settfb(size_t index, float value)
	{
		float *dp = mStart+index;
		assert(dp<mEnd);
		*dp = value;
	}
};



std::ostream& operator<<(std::ostream&, const SoftVector&);




#endif
// vim: ts=4 sw=4
