void FLaunchFromProfileCommand::Run(const FString& Params)
{
	// Get the name of the profile from the command line.
	FString ProfileName;
	FParse::Value(FCommandLine::Get(), TEXT("-PROFILENAME="), ProfileName);
	if (ProfileName.IsEmpty())
	{
		UE_LOG(LogUFECommands, Warning, TEXT("Profile name was found.  Please use '-PROFILENAME=' in your command line."));
		return;
	}
	
	// Loading the launcher services module to get the needed profile.
	ILauncherServicesModule& LauncherServicesModule = FModuleManager::LoadModuleChecked<ILauncherServicesModule>(TEXT("LauncherServices"));
	ILauncherProfileManagerRef ProfileManager = LauncherServicesModule.GetProfileManager();
	ILauncherProfilePtr Profile = ProfileManager->FindProfile(ProfileName);

	// Loading the Device Proxy Manager to get the needed Device Manager.
	ITargetDeviceServicesModule& DeviceServiceModule = FModuleManager::LoadModuleChecked<ITargetDeviceServicesModule>(TEXT("TargetDeviceServices"));
	ITargetDeviceProxyManagerRef DeviceProxyManager = DeviceServiceModule.GetDeviceProxyManager();

	UE_LOG(LogUFECommands, Display, TEXT("Begin the process of launching a project using the provided profile."));
	ILauncherRef LauncherRef = LauncherServicesModule.CreateLauncher();
	ILauncherWorkerPtr LauncherWorkerPtr = LauncherRef->Launch(DeviceProxyManager, Profile.ToSharedRef());

	// This will allow us to pipe the launcher messages into the command window.
	LauncherWorkerPtr.Get()->OnOutputReceived().AddStatic(&FLaunchFromProfileCommand::MessageReceived);
	// Allows us to exit this command once the launcher worker has completed or is canceled 
	LauncherWorkerPtr.Get()->OnCompleted().AddRaw(this, &FLaunchFromProfileCommand::LaunchCompleted);
	LauncherWorkerPtr.Get()->OnCanceled().AddRaw(this, &FLaunchFromProfileCommand::LaunchCanceled);

	TArray<ILauncherTaskPtr> TaskList;
	int32 NumOfTasks = LauncherWorkerPtr->GetTasks(TaskList);	
	UE_LOG(LogUFECommands, Display, TEXT("There are '%i' tasks to be completed."), NumOfTasks);

	// Holds the current element in the TaskList array.
	int32 TaskIndex = 0;
	// Holds the name of the current tasked.
	FString TriggeredTask;

	bTestRunning = true;
	while (bTestRunning)
	{
		if (TaskIndex >= NumOfTasks) continue;
		ILauncherTaskPtr CurrentTask = TaskList[TaskIndex];

		// Log the current task, but only once per run.
		if (CurrentTask->GetStatus() == ELauncherTaskStatus::Busy)
		{
			if (CurrentTask->GetDesc() == TriggeredTask) continue;

			TriggeredTask = *CurrentTask->GetDesc();
			UE_LOG(LogUFECommands, Display, TEXT("Current Task is %s"), *TriggeredTask);
			TaskIndex++;
		}
	}
}
static void CreateAndroidProfiles(const FProfileParameters& Params, FString ProjectPath, ILauncherProfileManagerRef ProfileManager)
{
	const FString ProjectName = FPaths::GetBaseFilename(ProjectPath);
	const FString AppProfileName = ProjectName + TEXT(" - Android APK");
	const FString DLCProfileName = ProjectName + TEXT(" - Android DLC");

	// Make profile names unique
	FString AppProfileNameUnique = AppProfileName;
	FString DLCProfileNameUnique = DLCProfileName;
	int32 UniqueCounter = 1;
	while (ProfileManager->FindProfile(AppProfileNameUnique).IsValid() 
			|| ProfileManager->FindProfile(DLCProfileNameUnique).IsValid())
	{
		AppProfileNameUnique = AppProfileName + FString::FromInt(UniqueCounter);
		DLCProfileNameUnique = DLCProfileName + FString::FromInt(UniqueCounter);
		UniqueCounter++;
	}


	// Create archive directory
	IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
	if (!PlatformFile.DirectoryExists(*Params.ArchiveDirectory))
	{
		PlatformFile.CreateDirectoryTree(*Params.ArchiveDirectory);
	}
	
	// Add App profile
	ILauncherProfileRef AppProfile = ProfileManager->AddNewProfile();
	SetupAndroidAppProfile(AppProfile, Params, ProjectPath);
	ProfileManager->ChangeProfileName(AppProfile, AppProfileNameUnique);
	ProfileManager->SaveJSONProfile(AppProfile);

	// Add DLC profile
	ILauncherProfileRef DLCProfile = ProfileManager->AddNewProfile();
	SetupAndroidDLCProfile(DLCProfile, Params, ProjectPath);
	ProfileManager->ChangeProfileName(DLCProfile, DLCProfileNameUnique);
	ProfileManager->SaveJSONProfile(DLCProfile);
}
void FIOSProfileWizard::HandleCreateLauncherProfile(const ILauncherProfileManagerRef& ProfileManager)
{
	const FVector2D WindowSize = FVector2D(940, 540);

	FText WindowTitle = LOCTEXT("CreateIOSProfileWizardTitle", "IOS App + DLC");
	FString ProjectPath = ProfileManager->GetProjectPath();
	
	TSharedRef<SWindow> AddProfileWindow =
		SNew(SWindow)
		.Title(WindowTitle)
		.ClientSize(WindowSize)
		.SizingRule(ESizingRule::FixedSize)
		.SupportsMinimize(false).SupportsMaximize(false);

	TSharedRef<SProfileWizardUI> ProfilesDialog =
		SNew(SProfileWizardUI)
		.ProfilePlatform(EProfilePlatform::IOS)
		.ProjectPath(ProjectPath)
		.OnCreateProfileEvent(FCreateProfileEvent::CreateStatic(&CreateIOSProfiles, ProjectPath, ProfileManager));

	AddProfileWindow->SetContent(ProfilesDialog);
	FSlateApplication::Get().AddWindow(AddProfileWindow);
}