#include "StdAfx.h"
#include "fs/FolderPack.h"
#include "fs/NativeFilesystem.h"
#include "tl/ptr.h"

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

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

FolderPack::FolderPack(AbsPathView location)
	: m_filesystem(tl::lend(native))
	, m_location(std::move(location))
{
	if (auto isFileResult = m_filesystem->isFile(m_location))
		TL_ASSERT(isFileResult.value() == false, "'{}' is a file", m_location);
}

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

FolderPack::FolderPack(tl::lent_ref<IFilesystem> filesystem, AbsPathView location)
	: m_filesystem(std::move(filesystem))
	, m_location(std::move(location))
{
	if (auto isFileResult = m_filesystem->isFile(m_location))
		TL_ASSERT(isFileResult.value() == false, "'{}' is a file", m_location);
}

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

OpenSourceResult FolderPack::openSource(AbsPathView path, SourceFlags flags) const
{
	return m_filesystem->openSource(convertToUnderlyingPath(path), flags);
}

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

OpenStreamSourceResult FolderPack::openStreamSource(AbsPathView path, SourceFlags flags) const
{
	return m_filesystem->openStreamSource(convertToUnderlyingPath(path), flags);
}

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

OpenMapSourceResult FolderPack::openMapSource(AbsPathView path, MapView mapView, SourceFlags flags) const
{
	return m_filesystem->openMapSource(convertToUnderlyingPath(path), mapView, flags);
}

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

IsFileResult FolderPack::isFile(AbsPathView path) const
{
	return m_filesystem->isFile(convertToUnderlyingPath(path));
}

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

IsFolderResult FolderPack::isFolder(AbsPathView path) const
{
	return m_filesystem->isFolder(convertToUnderlyingPath(path));
}

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

ExistsResult FolderPack::exists(AbsPathView path) const
{
	return m_filesystem->exists(convertToUnderlyingPath(path));
}

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

GetStatResult FolderPack::getStat(AbsPathView path) const
{
	return m_filesystem->getStat(convertToUnderlyingPath(path));
}

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

cppcoro::generator<EnumerateEntry> FolderPack::enumerate(AbsPath path) const
{
	const AbsPath localPath = convertToUnderlyingPath(path);
	for (EnumerateEntry ee : m_filesystem->enumerate(localPath))
		co_yield std::move(ee);
}

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

cppcoro::generator<EnumerateEntry> FolderPack::enumerateRecursively(AbsPath path) const
{
	const AbsPath localPath = convertToUnderlyingPath(path);
	for (EnumerateEntry ee : m_filesystem->enumerateRecursively(localPath))
		co_yield std::move(ee);
}

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

AbsPath FolderPack::convertToUnderlyingPath(AbsPathView path) const
{
	AbsPath filePath;
	filePath.reserve(m_location.size() + path.size());
	filePath = m_location;
	for (const tl::string& element : path)
		filePath.push_back(element);

	return filePath;
}

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

ConvertToNativePathResult FolderPack::convertToNativePath(AbsPathView path) const
{
	return m_filesystem->convertToNativePath(convertToUnderlyingPath(path));
}

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

}
