/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */

#pragma once

#include "ArchiveWriter.hpp"
#include <archive.h>
#include <ostream>

namespace OpenVulkano
{
	class ArchiveStreamBufferWriter final : public std::streambuf
	{
		ArchiveWriter* m_archive;
		size_t m_maxSize, m_written;

	public:
		ArchiveStreamBufferWriter(ArchiveWriter* archive, size_t size)
				: m_archive(archive), m_maxSize(size), m_written(0)
		{}

		std::streamsize xsputn(const char* s, std::streamsize n) override
		{
			if (!m_archive) return 0;
			if (m_maxSize < m_written + n) n = m_maxSize - m_written;
			if (n == 0) return 0;
			m_archive->ChkErr(archive_write_data(m_archive->m_archive, s, n));
			m_written += n;
			if (m_written == m_maxSize) Close();
			return n;
		}

		void Close()
		{
			if (!m_archive) return;
			if (m_maxSize > m_written && m_maxSize != FileDescription::UNKNOWN_SIZE)
			{ //Zero fill till eof
				std::vector<char> data(m_maxSize - m_written, 0);
				archive_write_data(m_archive->m_archive, data.data(), data.size());
			}
			m_archive->ChkErr(archive_write_finish_entry(m_archive->m_archive));
			m_archive = nullptr;
		}

		~ArchiveStreamBufferWriter() override
		{
			if (m_archive) Close();
		}
	};
}
