/*
 * Radio device interface
 *
 * Copyright (C) 2008-2014 Free Software Foundation, Inc.
 * Copyright (C) 2015 Ettus Research LLC
 *
 * SPDX-License-Identifier: AGPL-3.0+
 *
 * 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/>.
 * See the COPYING file in the main directory for details.
 */

#include "radioInterface.h"
#include "Resampler.h"
#include <Logger.h>
#include <Threads.h>

extern "C" {
#include "convert.h"
}

#define CHUNK		625
#define NUMCHUNKS	4

RadioInterface::RadioInterface(RadioDevice *wDevice, size_t tx_sps,
                               size_t rx_sps, size_t chans,
                               int wReceiveOffset, GSM::Time wStartTime)
  : mDevice(wDevice), mSPSTx(tx_sps), mSPSRx(rx_sps), mChans(chans),
    underrun(false), overrun(false), writeTimestamp(0), readTimestamp(0),
    receiveOffset(wReceiveOffset), mOn(false)
{
  mClock.set(wStartTime);
}

RadioInterface::~RadioInterface(void)
{
  close();
}

bool RadioInterface::init(int type)
{
  if ((type != RadioDevice::NORMAL) || !mChans) {
    LOG(ALERT) << "Invalid configuration";
    return false;
  }

  close();

  sendBuffer.resize(mChans);
  recvBuffer.resize(mChans);
  convertSendBuffer.resize(mChans);
  convertRecvBuffer.resize(mChans);
  mReceiveFIFO.resize(mChans);
  powerScaling.resize(mChans);

  for (size_t i = 0; i < mChans; i++) {
    sendBuffer[i] = new RadioBuffer(NUMCHUNKS, CHUNK * mSPSTx, 0, true);
    recvBuffer[i] = new RadioBuffer(NUMCHUNKS, CHUNK * mSPSRx, 0, false);

    convertSendBuffer[i] = new short[CHUNK * mSPSTx * 2];
    convertRecvBuffer[i] = new short[CHUNK * mSPSRx * 2];

    powerScaling[i] = 1.0;
  }

  return true;
}

void RadioInterface::close()
{
  for (std::vector<RadioBuffer*>::iterator it = sendBuffer.begin(); it != sendBuffer.end(); ++it)
          delete *it;
  for (std::vector<RadioBuffer*>::iterator it = recvBuffer.begin(); it != recvBuffer.end(); ++it)
          delete *it;
  for (std::vector<short*>::iterator it = convertSendBuffer.begin(); it != convertSendBuffer.end(); ++it)
          delete[] *it;
  for (std::vector<short*>::iterator it = convertRecvBuffer.begin(); it != convertRecvBuffer.end(); ++it)
          delete[] *it;
  sendBuffer.resize(0);
  recvBuffer.resize(0);
  convertSendBuffer.resize(0);
  convertRecvBuffer.resize(0);
}

double RadioInterface::fullScaleInputValue(void) {
  return mDevice->fullScaleInputValue();
}

double RadioInterface::fullScaleOutputValue(void) {
  return mDevice->fullScaleOutputValue();
}

int RadioInterface::setPowerAttenuation(int atten, size_t chan)
{
  double rfGain, digAtten;

  if (chan >= mChans) {
    LOG(ALERT) << "Invalid channel requested";
    return -1;
  }

  if (atten < 0.0)
    atten = 0.0;

  rfGain = setTxGain(mDevice->maxTxGain() - (double) atten, chan);
  digAtten = (double) atten - mDevice->maxTxGain() + rfGain;

  if (digAtten < 1.0)
    powerScaling[chan] = 1.0;
  else
    powerScaling[chan] = 1.0 / sqrt(pow(10, digAtten / 10.0));

  return atten;
}

int RadioInterface::radioifyVector(signalVector &wVector,
                                   size_t chan, bool zero)
{
  if (zero)
    sendBuffer[chan]->zero(wVector.size());
  else
    sendBuffer[chan]->write((float *) wVector.begin(), wVector.size());

  return wVector.size();
}

int RadioInterface::unRadioifyVector(signalVector *newVector, size_t chan)
{
  if (newVector->size() > recvBuffer[chan]->getAvailSamples()) {
    LOG(ALERT) << "Insufficient number of samples in receive buffer";
    return -1;
  }

  recvBuffer[chan]->read((float *) newVector->begin(), newVector->size());

  return newVector->size();
}

bool RadioInterface::tuneTx(double freq, size_t chan)
{
  return mDevice->setTxFreq(freq, chan);
}

bool RadioInterface::tuneRx(double freq, size_t chan)
{
  return mDevice->setRxFreq(freq, chan);
}

/** synchronization thread loop */
void *AlignRadioServiceLoopAdapter(RadioInterface *radioInterface)
{
  set_selfthread_name("AlignRadio");
  while (1) {
    sleep(60);
    radioInterface->alignRadio();
    pthread_testcancel();
  }
  return NULL;
}

void RadioInterface::alignRadio() {
  mDevice->updateAlignment(writeTimestamp+ (TIMESTAMP) 10000);
}

bool RadioInterface::start()
{
  if (mOn)
    return true;

  LOG(INFO) << "Starting radio device";
  if (mDevice->requiresRadioAlign())
        mAlignRadioServiceLoopThread.start(
                                (void * (*)(void*))AlignRadioServiceLoopAdapter,
                                (void*)this);

  if (!mDevice->start())
    return false;

  for (size_t i = 0; i < mChans; i++) {
    sendBuffer[i]->reset();
    recvBuffer[i]->reset();
  }

  writeTimestamp = mDevice->initialWriteTimestamp();
  readTimestamp = mDevice->initialReadTimestamp();

  mDevice->updateAlignment(writeTimestamp-10000);
  mDevice->updateAlignment(writeTimestamp-10000);

  mOn = true;
  LOG(INFO) << "Radio started";
  return true;
}

/*
 * Stop the radio device
 *
 * This is a pass-through call to the device interface. Because the underlying
 * stop command issuance generally doesn't return confirmation on device status,
 * this call will only return false if the device is already stopped.
 */
bool RadioInterface::stop()
{
  if (!mOn || !mDevice->stop())
    return false;

  mOn = false;
  return true;
}

void RadioInterface::driveTransmitRadio(std::vector<signalVector *> &bursts,
                                        std::vector<bool> &zeros)
{
  if (!mOn)
    return;

  for (size_t i = 0; i < mChans; i++)
    radioifyVector(*bursts[i], i, zeros[i]);

  while (pushBuffer());
}

int RadioInterface::driveReceiveRadio()
{
  radioVector *burst = NULL;

  if (!mOn)
    return 0;

  if (pullBuffer() < 0)
    return  -1;

  GSM::Time rcvClock = mClock.get();
  rcvClock.decTN(receiveOffset);
  unsigned tN = rcvClock.TN();
  int recvSz = recvBuffer[0]->getAvailSamples();
  const int symbolsPerSlot = gSlotLen + 8;
  int burstSize;

  if (mSPSRx == 4)
    burstSize = 625;
  else
    burstSize = symbolsPerSlot + (tN % 4 == 0);

  /*
   * Pre-allocate head room for the largest correlation size
   * so we can later avoid a re-allocation and copy
   * */
  size_t head = GSM::gRACHSynchSequenceTS0.size();

  /*
   * Form receive bursts and pass up to transceiver. Use repeating
   * pattern of 157-156-156-156 symbols per timeslot
   */
  while (recvSz > burstSize) {
    for (size_t i = 0; i < mChans; i++) {
      burst = new radioVector(rcvClock, burstSize, head);
      unRadioifyVector(burst->getVector(), i);

      if (mReceiveFIFO[i].size() < 32)
        mReceiveFIFO[i].write(burst);
      else
        delete burst;
    }

    mClock.incTN();
    rcvClock.incTN();
    recvSz -= burstSize;

    tN = rcvClock.TN();

    if (mSPSRx != 4)
      burstSize = (symbolsPerSlot + (tN % 4 == 0)) * mSPSRx;
  }

  return 1;
}

bool RadioInterface::isUnderrun()
{
  bool retVal;
  /* atomically get previous value of "underrun" and set the var to false */
  retVal = osmo_trx_sync_fetch_and_and(&underrun, false);
  return retVal;
}

VectorFIFO* RadioInterface::receiveFIFO(size_t chan)
{
  if (chan >= mReceiveFIFO.size())
    return NULL;

  return &mReceiveFIFO[chan];
}

double RadioInterface::setRxGain(double dB, size_t chan)
{
  return mDevice->setRxGain(dB, chan);
}

double RadioInterface::setTxGain(double dB, size_t chan)
{
  return mDevice->setTxGain(dB, chan);
}

/* Receive a timestamped chunk from the device */
int RadioInterface::pullBuffer()
{
  bool local_underrun;
  int numRecv;
  size_t segmentLen = recvBuffer[0]->getSegmentLen();

  if (recvBuffer[0]->getFreeSegments() <= 0)
    return -1;

  /* Outer buffer access size is fixed */
  numRecv = mDevice->readSamples(convertRecvBuffer,
                                segmentLen,
                                &overrun,
                                readTimestamp,
                                &local_underrun);

  if ((size_t) numRecv != segmentLen) {
          LOG(ALERT) << "Receive error " << numRecv;
          return -1;
  }

  for (size_t i = 0; i < mChans; i++) {
    convert_short_float(recvBuffer[i]->getWriteSegment(),
			convertRecvBuffer[i],
			segmentLen * 2);
  }

  osmo_trx_sync_or_and_fetch(&underrun, local_underrun);
  readTimestamp += numRecv;
  return 0;
}

/* Send timestamped chunk to the device with arbitrary size */
bool RadioInterface::pushBuffer()
{
  bool local_underrun;
  size_t numSent, segmentLen = sendBuffer[0]->getSegmentLen();

  if (sendBuffer[0]->getAvailSegments() < 1)
    return false;

  for (size_t i = 0; i < mChans; i++) {
    convert_float_short(convertSendBuffer[i],
                        (float *) sendBuffer[i]->getReadSegment(),
                        powerScaling[i],
                        segmentLen * 2);
  }

  /* Send the all samples in the send buffer */
  numSent = mDevice->writeSamples(convertSendBuffer,
                                 segmentLen,
                                 &local_underrun,
                                 writeTimestamp);
  osmo_trx_sync_or_and_fetch(&underrun, local_underrun);
  writeTimestamp += numSent;

  return true;
}
