Pith - whittle
#pragma once
#include "model/FileRecord.h"
#include <QThread>
#include <QString>
#include <QList>
#include <QSet>
#include <atomic>

namespace whittle {

	class MergeController : public QThread {
		Q_OBJECT
	public:
		enum class Skip { IllegalName, CaseCollision, IoError };

		MergeController(QList<FileRecord> items, QList<FileRecord> deletes,
			QString usbMount, QObject* parent = nullptr);
		void cancel() { m_cancel.store(true, std::memory_order_relaxed); }

		qint64 totalBytes() const { return m_totalBytes; }
		int    fileCount()  const { return m_fileCount;  }

		signals:
		void progress(QString currentRel, qint64 bytesDone, int filesDone);
		void copied(QString relPath);
		void removed(QString relPath, bool ok);
		void skipped(QString relPath, int reason);
		void deviceLost();
		void done(bool canceled);

	protected:
		void run() override;

	private:
		enum class Result { Ok, IllegalName, CaseCollision, IoError, DeviceLost, Canceled };
		Result copyFile(const FileRecord& rec, const QString& dest,
			qint64& bytesDone, int filesDone, bool caseInsensitive);
		Result makeDir (const FileRecord& rec, const QString& dest);
		bool deviceGone() const;
		Result destError(const char* op, const QByteArray& path) const;

		QList<FileRecord> m_items;
		QList<FileRecord> m_deletes;
		QString m_usbMount;
		qint64  m_totalBytes = 0;
		int     m_fileCount  = 0;
		bool    m_fatNames = false;
		QSet<QString> m_writtenLower;
		std::atomic<bool> m_cancel{false};
	};

}