bool FSurveyTitleLocalStorage::EnumerateFiles(const FPagedQuery& Page)
{
	if (!IFileManager::Get().DirectoryExists(*RootDirectory))
	{
		TriggerOnEnumerateFilesCompleteDelegates(false, TEXT("Directory does not exist"));
		return false;
	}

	const FString WildCard = FString::Printf(TEXT("%s/*"), *RootDirectory);

	TArray<FString> Filenames;
	IFileManager::Get().FindFiles(Filenames, *WildCard, true, false);

	for (int32 FileIdx = 0; FileIdx < Filenames.Num(); ++FileIdx)
	{
		const FString Filename = Filenames[FileIdx];

		FCloudFileHeader NewHeader;
		NewHeader.FileName = Filename;
		NewHeader.DLName = Filename + Lex::ToString(FileIdx);
		NewHeader.FileSize = 0;
		NewHeader.Hash.Empty();

		FileHeaders.Add( NewHeader );
	}

	TriggerOnEnumerateFilesCompleteDelegates(true, FString());

	return true;
}
bool FLocalNewsFeedTitleFile::EnumerateFiles(const FPagedQuery& Page)
{
	const FString WildCard = FPaths::Combine(*RootDirectory, TEXT("*"));

	TArray<FString> Filenames;
	IFileManager::Get().FindFiles(Filenames, *WildCard, true, false);

	bool Success = Filenames.Num() > 0;

	if (Success)
	{
		for (int32 FileIdx = 0; FileIdx < Filenames.Num(); ++FileIdx)
		{
			const FString Filename = Filenames[FileIdx];

			FCloudFileHeader NewHeader;
			NewHeader.FileName = Filename;
			NewHeader.DLName = Filename + FileIdx;
			NewHeader.FileSize = 0;
			NewHeader.Hash.Empty();

			FileHeaders.Add( NewHeader );
		}
	}

	TriggerOnEnumerateFilesCompleteDelegates(Success);

	return Success;
}
bool FCdnNewsFeedTitleFile::EnumerateFiles(const FPagedQuery& Page)
{
	// Make sure an enumeration request  is not currently pending
	if(!EnumerateFilesRequests.IsEmpty())
	{
		UE_LOG(LogEpicStorage, Warning, TEXT("EnumerateFiles request failed. Request already in progress."));
		TriggerOnEnumerateFilesCompleteDelegates(false);
		return false;
	}

	// Create the Http request and add to pending request list
	TSharedRef<class IHttpRequest> HttpRequest = FHttpModule::Get().CreateRequest();
	EnumerateFilesRequests.Enqueue(&HttpRequest.Get());

	HttpRequest->OnProcessRequestComplete().BindThreadSafeSP(this, &FCdnNewsFeedTitleFile::EnumerateFiles_HttpRequestComplete);
	HttpRequest->SetURL( IndexUrl );
	HttpRequest->SetVerb(TEXT("GET"));
	HttpRequest->ProcessRequest();
	return true;
	
}	
void FCdnNewsFeedTitleFile::EnumerateFiles_HttpRequestComplete(FHttpRequestPtr HttpRequest, FHttpResponsePtr HttpResponse, bool bSucceeded)
{
	IHttpRequest* Request;
	EnumerateFilesRequests.Dequeue(Request);

	bool bResult = false;
	FString ResponseStr, ErrorStr;

	if (bSucceeded && HttpResponse.IsValid())
	{
		ResponseStr = HttpResponse->GetContentAsString();
		if (EHttpResponseCodes::IsOk(HttpResponse->GetResponseCode()))
		{
			UE_LOG(LogEpicStorage, Verbose, TEXT("EnumerateFiles request complete. url=%s code=%d response=%s"), 
				*HttpRequest->GetURL(), HttpResponse->GetResponseCode(), *ResponseStr);

			FileHeaders.Empty();

			// Make sure the response is an array
			if (!ResponseStr.StartsWith(TEXT("[")))
			{
				ResponseStr = FString(TEXT("[")) + ResponseStr + FString(TEXT("]"));
			}

			// Json parser expects arrays to always be wrapped with object
			FString ResponseStrJson = FString(TEXT("{\"files\":")) + ResponseStr + FString(TEXT("}"));
			// Create the Json parser
			TSharedPtr<FJsonObject> JsonObject;
			TSharedRef<TJsonReader<> > JsonReader = TJsonReaderFactory<>::Create(ResponseStrJson);

			if (FJsonSerializer::Deserialize(JsonReader,JsonObject) &&
				JsonObject.IsValid())
			{
				// Parse the array of file headers
				TArray<TSharedPtr<FJsonValue> > JsonFileHeaders = JsonObject->GetArrayField(TEXT("files"));
				for (TArray<TSharedPtr<FJsonValue> >::TConstIterator It(JsonFileHeaders); It; ++It)
				{
					TSharedPtr<FJsonObject> JsonFileHeader = (*It)->AsObject();
					if (JsonFileHeader.IsValid())
					{
						FCloudFileHeader FileHeader;
						if (JsonFileHeader->HasField(TEXT("hash")))
						{
							FileHeader.Hash = JsonFileHeader->GetStringField(TEXT("hash"));
						}
						if (JsonFileHeader->HasField(TEXT("uniqueFilename")))
						{
							FileHeader.DLName = JsonFileHeader->GetStringField(TEXT("uniqueFilename"));
						}
						if (JsonFileHeader->HasField(TEXT("filename")))
						{
							FileHeader.FileName = JsonFileHeader->GetStringField(TEXT("filename"));
						}
						if (JsonFileHeader->HasField(TEXT("length")))
						{
							FileHeader.FileSize = FMath::TruncToInt(JsonFileHeader->GetNumberField(TEXT("length")));
						}

						if (FileHeader.FileName.IsEmpty())
						{
							FileHeader.FileName = FileHeader.DLName;
						}

						if (FileHeader.Hash.IsEmpty() ||
							FileHeader.DLName.IsEmpty())
						{
							UE_LOG(LogEpicStorage, Warning, TEXT("Invalid file entry hash=%s dlname=%s filename=%s"),
								*FileHeader.Hash, *FileHeader.DLName, *FileHeader.FileName);
						}
						else
						{
							FileHeaders.Add(FileHeader);
						}
					}
				}
				bResult = true;
			}	
			else
			{
				ErrorStr = FString::Printf(TEXT("Invalid response payload=%s"),
					*ResponseStr);
			}
			
		}
		else
		{
			ErrorStr = FString::Printf(TEXT("Invalid response. code=%d error=%s"),
				HttpResponse->GetResponseCode(), *ResponseStr);
		}
	}


	if (!ErrorStr.IsEmpty())
	{
		UE_LOG(LogEpicStorage, Warning, TEXT("EnumerateFiles request failed. %s"), *ErrorStr);
	}

	TriggerOnEnumerateFilesCompleteDelegates(bResult);
}