#include "ReportTransporter.hpp"

namespace otx {
	namespace jidu {

		ReportTransporter* ReportTransporter::mDEFAULT = nullptr;
		ReportTransporter* ReportTransporter::getDefault() {
			if (mDEFAULT == nullptr) {
				mDEFAULT = new ReportTransporter();
			}
			return mDEFAULT;
		}

		ReportTransporter::ReportTransporter() {
			this->mThread = nullptr;
			this->mTransportAction = nullptr;
			this->mIsRunning.store(false, std::memory_order_relaxed);
		}

		ReportTransporter::~ReportTransporter() {
			stop();
			this->mQueue.clear();
		}

		void ReportTransporter::start() {
			if (!this->mIsRunning.load(std::memory_order_relaxed)) {
				this->mIsRunning.store(true, std::memory_order_relaxed);
				this->mThread = new std::thread(threadWork, this);
				this->mThread->detach();
			}
		}
		void ReportTransporter::stop() {
			if (this->mIsRunning.load(std::memory_order_relaxed)) {
				this->mIsRunning.store(false, std::memory_order_relaxed);
				if (this->mThread) {
					if (this->mThread->joinable()) {
						this->mThread->join();
					}
					delete this->mThread;
					this->mThread = nullptr;
				}
			}
		}
		ReportQueue* ReportTransporter::getQueue() {
			return &this->mQueue;
		}
		void ReportTransporter::setAction(ReportTransportAction* action) {
			this->mTransportAction = action;
		}

		void ReportTransporter::threadWork(ReportTransporter* transporter) {
			while (transporter->mIsRunning.load(std::memory_order_relaxed)) {
				if (transporter->mQueue.size() > 0) {
					if (transporter->mTransportAction) {
						std::string* reportText = transporter->mQueue.deque();
						int state = transporter->mTransportAction->doTransport(reportText);
						if (state != 0) {
							// 外部传输失败，重新塞回队列。
							transporter->mQueue.enque(reportText);
							printf("report text transport failed(%d), reenque transporter queue.\r\n", state);
						}
						else {
							// 按照约定，出队后的数据由使用方用完后释放。
							delete reportText;
							printf("transport ok,remain %d items.\r\n", (int)transporter->mQueue.size());
						}
					}
					else {
						// 没有Action，多等一会。
						std::this_thread::sleep_for(std::chrono::milliseconds(10));
					}
				}
				else {
					// 没有数据，多等一会。
					std::this_thread::sleep_for(std::chrono::milliseconds(10));
				}
			}
			printf("report transporter thread end.\r\n");
		}

	} // namespace jidu
} // namespace otx