package brn.swans.radio.biterrormodels;

import java.io.IOException;

import jist.swans.Constants;
import brn.analysis.dump.BitErrorAggregator;
import brn.swans.radio.TransmissionMode;
import brn.swans.radio.RadioNoiseAdditiveBER.ChunkErrorRates;


public class MaskedPackets extends BitErrorModel {

  private double backgroundNoise_mW;
  private BitErrorMasks maskStorage;


  public MaskedPackets(double noise_mW, String referenceDump, String[] dumps) {
    this.backgroundNoise_mW = noise_mW;
    BitErrorAggregator dumpStorage = null;
    try {
      dumpStorage = new BitErrorAggregator(referenceDump);
      for (int dump = 0; dump < dumps.length; ++dump) {
        dumpStorage.analyze(dumps[dump]);
      }
    } catch (IOException e) {
      // TODO Automatisch erstellter Catch-Block
      e.printStackTrace();
    }
    maskStorage = dumpStorage.getErrorMasks();
  }

  private byte calculateRssi(double snir) {
    // static constant noise is used as measurement doesn't know about noise
    double signal_mW = snir * backgroundNoise_mW;
    byte rssi = (byte) Math.min(10 * Math.log(signal_mW)
        / Constants.log10 + 95, 60.);
    return rssi;
  }

  private double getChunkSuccessRate(double snir, int nbits, TransmissionMode mode) {
    byte rssi = calculateRssi(snir);
    byte rate = (byte)(mode.getDataRate() / 1000000);
    return maskStorage.getChunkSuccessRate(nbits, rssi, rate);
  }

  @Override
  public int treatChunk(ChunkErrorRates rates, int bitPosition, long current, long previous, double snr) {
    TransmissionMode mode = rates.getMode();
    int dataBits = mode.getNumDataBits(current - previous);

    double csr = getChunkSuccessRate(snr, dataBits, mode);//mode.getCachedSuccessRate(snr, dataBits);
    BitErrorMask chunkErrorMask = createErrors(dataBits, snr, mode);

    rates.updateChunk(bitPosition, csr, chunkErrorMask);

    return dataBits;
  }

  @Override
  protected BitErrorMask createErrors(int l, double snr, TransmissionMode mode) {
    byte rssi  = calculateRssi(snr);
    byte rate = (byte)(mode.getDataRate() / 1000000);
    return maskStorage.get(l, rssi, rate);
  }

}
