#pragma once

#include "fs/Api.h"
#include <tl/memory_buffer.h>
#include <tl/span.h>
#include <tl/vector.h>
#include <tl/result.h>
#include <tl/optional.h>
#include "fs/zip/ZipPack.h"

namespace fs
{
//////////////////////////////////////////////////////////////////////////

class ISource;
class IStreamSink;
class ISink;

//////////////////////////////////////////////////////////////////////////

class FS_API ZipWriter
{
public:
	//0 - no compression (Store)
	//9 - max compression (Deflate)
	using Compression = uint8_t;

	ZipWriter(ISink& sink);
	~ZipWriter();

	tl::result<void> addBuffer(tl::string name, Compression compression, tl::span<const uint8_t> buffer);
	tl::result<void> addBuffer(tl::string name, time_t lastModificationTime, Compression compression, tl::span<const uint8_t> buffer);
	tl::result<void> addBuffer(tl::string name,
		tl::span<const uint8_t> comment,
		tl::span<const uint8_t> extraField,
		time_t lastModificationTime,
		Compression compression,
		tl::span<const uint8_t> buffer);

	tl::result<void> addFile(tl::string name, Compression compression, ISource& source);
	tl::result<void> addFile(tl::string name, time_t lastModificationTime, Compression compression, ISource& source);
	tl::result<void> addFile(tl::string name,
		tl::span<const uint8_t> comment,
		tl::span<const uint8_t> extraField,
		time_t lastModificationTime,
		Compression compression,
		ISource& source);

	void finish();

private:
	tl::result<uint64_t> _addSource(tl::string name,
		tl::span<const uint8_t> comment,
		tl::span<const uint8_t> extraField,
		time_t lastModificationTime,
		Compression compression,
		zip_source* source);

	ISink& m_sink;
	tl::unique_ptr<zip> m_zipArchive;
};
	

//////////////////////////////////////////////////////////////////////////
}
