#pragma once
/*
 * (C) 2022 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
 * All Rights Reserved
 *
 * Author: Eric Wild <ewild@sysmocom.de>
 *
 * 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/>.
 *
 */

#include <atomic>
#include <cassert>
#include <complex>
#include <cstdint>
#include <mutex>
#include <iostream>
// #include <thread>

#if defined(BUILDBLADE)
#include "bladerf_specific.h"
#define BASET blade_hw<ms_trx>
#elif defined(BUILDUHD)
#include "uhd_specific.h"
#define BASET uhd_hw<ms_trx>
#else
#error wat? no device..
#endif

#include "Complex.h"
#include "GSMCommon.h"
#include "itrq.h"
#include "threadpool.h"
#include "threadsched.h"

const unsigned int ONE_TS_BURST_LEN = (3 + 58 + 26 + 58 + 3 + 8.25) * 4 /*sps*/;
const unsigned int SCH_LEN_SPS = (ONE_TS_BURST_LEN * 8 /*ts*/ * 12 /*frames*/);

template <typename T>
void clamp_array(T *start2, unsigned int len, T max)
{
	for (unsigned int i = 0; i < len; i++) {
		const T t1 = start2[i] < -max ? -max : start2[i];
		const T t2 = t1 > max ? max : t1;
		start2[i] = t2;
	}
}

namespace cvt_internal
{

template <typename SRC_T, typename ST>
void convert_and_scale_i(float *dst, const SRC_T *src, unsigned int src_len, ST scale)
{
	for (unsigned int i = 0; i < src_len; i++)
		dst[i] = static_cast<float>(src[i]) * scale;
}

template <typename DST_T, typename ST>
void convert_and_scale_i(DST_T *dst, const float *src, unsigned int src_len, ST scale)
{
	for (unsigned int i = 0; i < src_len; i++)
		dst[i] = static_cast<DST_T>(src[i] * scale);
}

template <typename ST>
void convert_and_scale_i(float *dst, const float *src, unsigned int src_len, ST scale)
{
	for (unsigned int i = 0; i < src_len; i++)
		dst[i] = src[i] * scale;
}

template <typename T>
struct is_complex : std::false_type {
	using baset = T;
	static const unsigned int len_mul = 1;
};

template <typename T>
struct is_complex<std::complex<T>> : std::true_type {
	using baset = typename std::complex<T>::value_type;
	static const unsigned int len_mul = 2;
};

template <typename T>
struct is_complex<Complex<T>> : std::true_type {
	using baset = typename Complex<T>::value_type;
	static const unsigned int len_mul = 2;
};

} // namespace cvt_internal

template <typename DST_T, typename SRC_T, typename ST>
void convert_and_scale(DST_T *dst, const SRC_T *src, unsigned int src_len, ST scale)
{
	using vd = typename cvt_internal::is_complex<DST_T>::baset;
	using vs = typename cvt_internal::is_complex<SRC_T>::baset;
	return cvt_internal::convert_and_scale_i((vd *)dst, (vs *)src, src_len, scale);
}

template <typename array_t>
float normed_abs_sum(array_t *src, int len)
{
	using vd = typename cvt_internal::is_complex<array_t>::baset;
	auto len_mul = cvt_internal::is_complex<array_t>::len_mul;
	auto ptr = reinterpret_cast<const vd *>(src);
	float sum = 0;
	for (unsigned int i = 0; i < len * len_mul; i++)
		sum += std::abs(ptr[i]);
	sum /= len * len_mul;
	return sum;
}

struct one_burst {
	one_burst()
	{
	}
	GSM::Time gsmts;
	union {
		blade_sample_type burst[ONE_TS_BURST_LEN];
		char sch_bits[148];
	};
};

using rx_queue_t = spsc_cond_timeout<4, one_burst, true, false>;

enum class SCH_STATE { SEARCHING, FOUND };

class dummylog : private std::streambuf {
	std::ostream null_stream;

    public:
	dummylog() : null_stream(this){};
	~dummylog() override{};
	std::ostream &operator()()
	{
		return null_stream;
	}
	int overflow(int c) override
	{
		return c;
	}
};

// keeps relationship between gsm time and (continuously adjusted) ts
class time_keeper {
	GSM::Time global_time_keeper;
	int64_t global_ts_keeper;
	std::mutex m;

    public:
	time_keeper() : global_time_keeper(0), global_ts_keeper(0)
	{
	}

	void set(GSM::Time t, int64_t ts)
	{
		std::lock_guard<std::mutex> g(m);
		global_time_keeper = t;
		global_ts_keeper = ts;
	}
	void inc_both()
	{
		std::lock_guard<std::mutex> g(m);
		global_time_keeper.incTN(1);
		global_ts_keeper += ONE_TS_BURST_LEN;
	}
	void inc_and_update(int64_t new_ts)
	{
		std::lock_guard<std::mutex> g(m);
		global_time_keeper.incTN(1);
		global_ts_keeper = new_ts;
	}
	void inc_and_update_safe(int64_t new_ts)
	{
		std::lock_guard<std::mutex> g(m);
		auto diff = new_ts - global_ts_keeper;
		assert(diff < 1.5 * ONE_TS_BURST_LEN);
		assert(diff > 0.5 * ONE_TS_BURST_LEN);
		global_time_keeper.incTN(1);
		global_ts_keeper = new_ts;
	}
	void dec_by_one()
	{
		std::lock_guard<std::mutex> g(m);
		global_time_keeper.decTN(1);
		global_ts_keeper -= ONE_TS_BURST_LEN;
	}
	auto get_ts()
	{
		std::lock_guard<std::mutex> g(m);
		return global_ts_keeper;
	}
	auto gsmtime()
	{
		std::lock_guard<std::mutex> g(m);
		return global_time_keeper;
	}
	void get_both(GSM::Time *t, int64_t *ts)
	{
		std::lock_guard<std::mutex> g(m);
		*t = global_time_keeper;
		*ts = global_ts_keeper;
	}
};

// used to globally initialize the sched/hw information
struct sched_hw_info {
	int hw_cpus;
	sched_params::target hw_target;

	sched_hw_info()
	{
		hw_cpus = std::thread::hardware_concurrency();
		hw_target = hw_cpus > 4 ? sched_params::target::ODROID : sched_params::target::PI4;
		set_sched_target(hw_target);
		std::cerr << "scheduling for: " << (hw_cpus > 4 ? "odroid" : "pi4") << std::endl;
	}
};

struct ms_trx : public BASET, public sched_hw_info {
	using base = BASET;
	static dummylog dummy_log;
	unsigned int mTSC;
	unsigned int mBSIC;
	int timing_advance;
	bool use_va;

	pthread_t lower_rx_task;
	pthread_t lower_tx_task;

	// provides bursts to upper rx thread
	rx_queue_t rxqueue;

	blade_sample_type *first_sch_buf;
	blade_sample_type *burst_copy_buffer;

	uint64_t first_sch_buf_rcv_ts;
	std::atomic<bool> rcv_done;
	std::atomic<bool> sch_thread_done;

	int64_t temp_ts_corr_offset = 0;
	int64_t first_sch_ts_start = -1;

	time_keeper timekeeper;
	single_thread_pool worker_thread; // uses base class sched target hw info

	void start_lower_ms();
	std::atomic<bool> upper_is_ready;
	void set_upper_ready(bool is_ready);

	bool handle_sch_or_nb();
	bool handle_sch(bool first = false);
	bool decode_sch(char *bits, bool update_global_clock);
	SCH_STATE search_for_sch(dev_buf_t *rcd);
	void grab_bursts(dev_buf_t *rcd);

	int init_dev_and_streams();
	void stop_threads();
	void *rx_cb(ms_trx *t);
	void *tx_cb();
	void maybe_update_gain(one_burst &brst);

	ms_trx(struct mssdr_cfg *cfgdata)
		: BASET(cfgdata), mTSC(0), mBSIC(0), timing_advance(0), use_va(cfgdata->use_va), rxqueue(),
		  first_sch_buf(new blade_sample_type[SCH_LEN_SPS]),
		  burst_copy_buffer(new blade_sample_type[ONE_TS_BURST_LEN]), first_sch_buf_rcv_ts(0),
		  rcv_done{ false }, sch_thread_done{ false }, upper_is_ready(false)
	{
	}

	virtual ~ms_trx()
	{
		delete[] burst_copy_buffer;
		delete[] first_sch_buf;
	}
	bh_fn_t rx_bh();
	bh_fn_t tx_bh();

	void submit_burst(blade_sample_type *buffer, int len, GSM::Time);
	void set_ta(int val)
	{
		assert(val > -127 && val < 128);
		timing_advance = val * 4;
	}
};
