FCrashWERContext::FCrashWERContext( const FString& WERXMLFilepath )
	: FPrimaryCrashProperties()
{
	ReadXML( WERXMLFilepath );
	CrashGUID = FPaths::GetCleanFilename( FPaths::GetPath( WERXMLFilepath ) );

	const bool bIsValid = XmlFile->IsValid();
	if (bIsValid)
	{
		FString BuildVersion;
		FString BranchName;
		uint32 BuiltFromCL = 0;
		int EngineVersionComponents = 0;

		GetCrashProperty( GameName, TEXT( "ProblemSignatures" ), TEXT( "Parameter0" ) );

		GetCrashProperty( BuildVersion, TEXT( "ProblemSignatures" ), TEXT( "Parameter1" ) );
		if (!BuildVersion.IsEmpty())
		{
			EngineVersionComponents++;
		}

		FString Parameter8Value;
		GetCrashProperty( Parameter8Value, TEXT( "ProblemSignatures" ), TEXT( "Parameter8" ) );
		if (!Parameter8Value.IsEmpty())
		{
			TArray<FString> ParsedParameters8;
			Parameter8Value.ParseIntoArray( ParsedParameters8, TEXT( "!" ), false );

			if (ParsedParameters8.Num() > 1)
			{
				CommandLine = FGenericCrashContext::UnescapeXMLString( ParsedParameters8[1] );
				CrashDumpMode = CommandLine.AsString().Contains( TEXT( "-fullcrashdump" ) ) ? ECrashDumpMode::FullDump : ECrashDumpMode::Default;
			}

			if (ParsedParameters8.Num() > 2)
			{
				ErrorMessage = ParsedParameters8[2];
			}
		}

		RestartCommandLine = CommandLine.AsString();

		FString Parameter9Value;
		GetCrashProperty( Parameter9Value, TEXT( "ProblemSignatures" ), TEXT( "Parameter9" ) );
		if (!Parameter9Value.IsEmpty())
		{
			TArray<FString> ParsedParameters9;
			Parameter9Value.ParseIntoArray( ParsedParameters9, TEXT( "!" ), false );

			if (ParsedParameters9.Num() > 0)
			{
				BranchName = ParsedParameters9[0].Replace( TEXT( "+" ), TEXT( "/" ) );

				const FString DepotRoot = TEXT( "//depot/" );
				if (BranchName.StartsWith( DepotRoot ))
				{
					BranchName = BranchName.Mid( DepotRoot.Len() );
				}
				EngineVersionComponents++;
			}

			if (ParsedParameters9.Num() > 1)
			{
				const FString BaseDirectory = ParsedParameters9[1];

				TArray<FString> SubDirs;
				BaseDirectory.ParseIntoArray( SubDirs, TEXT( "/" ), true );
				const int SubDirsNum = SubDirs.Num();
				const FString PlatformName = SubDirsNum > 0 ? SubDirs[SubDirsNum - 1] : TEXT( "" );

				FString Product;
				GetCrashProperty( Product, TEXT( "OSVersionInformation" ), TEXT( "Product" ) );
				if (Product.Len() > 0)
				{
					PlatformFullName = FString::Printf( TEXT( "%s [%s]" ), *PlatformName, *Product );
				}
				else
				{
					PlatformFullName = PlatformName;
				}
			}

			if (ParsedParameters9.Num() > 2)
			{
				EngineMode = ParsedParameters9[2];
			}

			if (ParsedParameters9.Num() > 3)
			{
				TTypeFromString<uint32>::FromString( BuiltFromCL, *ParsedParameters9[3] );
				EngineVersionComponents++;
			}
		}

		// We have all three components of the engine version, so initialize it.
		if (EngineVersionComponents == 3)
		{
			InitializeEngineVersion( BuildVersion, BranchName, BuiltFromCL );
		}

		bHasPrimaryData = true;
	}
}
FCrashDescription::FCrashDescription( FString WERXMLFilepath ) :
	// WER XML files are forced to be in the first version
	CrashDescriptionVersion( ECrashDescVersions::VER_1_NewCrashFormat ),
	BuiltFromCL( -1 ),
	TimeOfCrash( FDateTime::UtcNow() ),
	bHasMiniDumpFile( false ),
	bHasLogFile( false ),
	bHasVideoFile( false ),
	bHasCompleteData( false )
{
	InitializeIDs();

	// This is for the current system that uses files from Windows Error Reporting.
	// Will be replaced with the unified version soon.
	FXmlFile XmlFile( WERXMLFilepath );

	ReportName = FPaths::GetPath( WERXMLFilepath );
	FPaths::NormalizeDirectoryName( ReportName );
	// Grab the last component...
	ReportName = FPaths::GetCleanFilename( ReportName );

	const bool bIsValid = XmlFile.IsValid();
	if( bIsValid )
	{
		const FXmlNode* OSVersionInformationNode = XmlFile.GetRootNode()->FindChildNode( TEXT( "OSVersionInformation" ) );
		const FXmlNode* ProblemSignaturesNode = XmlFile.GetRootNode()->FindChildNode( TEXT( "ProblemSignatures" ) );
		const FXmlNode* DynamicSignaturesNode = XmlFile.GetRootNode()->FindChildNode( TEXT( "DynamicSignatures" ) );

		FString Product;
		int EngineVersionComponents = 0;

		if( OSVersionInformationNode )
		{
			const FXmlNode* ProductNode = OSVersionInformationNode->FindChildNode( TEXT( "Product" ) );
			if( ProductNode )
			{
				Product = ProductNode->GetContent();
			}
		}

		if( ProblemSignaturesNode )
		{
			const FXmlNode* GameNameNode = ProblemSignaturesNode->FindChildNode( TEXT( "Parameter0" ) );
			if( GameNameNode )
			{
				GameName = GameNameNode->GetContent();
			}

			const FXmlNode* BuildVersionNode = ProblemSignaturesNode->FindChildNode( TEXT( "Parameter1" ) );
			if( BuildVersionNode )
			{
				BuildVersion = BuildVersionNode->GetContent();
				EngineVersionComponents++;
			}

			const FXmlNode* Parameter8Node = ProblemSignaturesNode->FindChildNode( TEXT( "Parameter8" ) );
			if( Parameter8Node )
			{
				const FString Parameter8Value = Parameter8Node->GetContent();

				TArray<FString> ParsedParameters8;
				Parameter8Value.ParseIntoArray( ParsedParameters8, TEXT( "!" ), false );

				if( ParsedParameters8.Num() > 1 )
				{
					CommandLine = UnescapeXMLString( ParsedParameters8[1] );
				}

				if( ParsedParameters8.Num() > 2 )
				{
					ErrorMessage.Add( ParsedParameters8[2] );
				}
			}

			const FXmlNode* Parameter9Node = ProblemSignaturesNode->FindChildNode( TEXT( "Parameter9" ) );
			if( Parameter9Node )
			{
				const FString Parameter9Value = Parameter9Node->GetContent();

				TArray<FString> ParsedParameters9;
				Parameter9Value.ParseIntoArray( ParsedParameters9, TEXT( "!" ), false );

				if( ParsedParameters9.Num() > 0 )
				{
					BranchName = ParsedParameters9[0].Replace( TEXT( "+" ), TEXT( "/" ) );

					const FString DepotRoot = TEXT( "//depot/" );
					if( BranchName.StartsWith( DepotRoot ) )
					{
						BranchName = BranchName.Mid( DepotRoot.Len() );
					}
					EngineVersionComponents++;
				}

				if( ParsedParameters9.Num() > 1 )
				{
					const FString BaseDirectory = ParsedParameters9[1];

					TArray<FString> SubDirs;
					BaseDirectory.ParseIntoArray( SubDirs, TEXT( "/" ), true );
					const int SubDirsNum = SubDirs.Num();
					const FString PlatformName = SubDirsNum > 0 ? SubDirs[SubDirsNum - 1] : TEXT("");
					if( Product.Len() > 0 )
					{
						Platform = FString::Printf( TEXT( "%s [%s]" ), *PlatformName, *Product );
					}
					else
					{
						Platform = PlatformName;
					}
				}

				if( ParsedParameters9.Num() > 2 )
				{
					EngineMode = ParsedParameters9[2];
				}

				if( ParsedParameters9.Num() > 3 )
				{
					TTypeFromString<uint32>::FromString( BuiltFromCL, *ParsedParameters9[3] );
					EngineVersionComponents++;
				}
			}
		}

		if( DynamicSignaturesNode )
		{
			const FXmlNode* LanguageNode = DynamicSignaturesNode->FindChildNode( TEXT( "Parameter2" ) );
			if( LanguageNode )
			{
				LanguageLCID = LanguageNode->GetContent();
			}
		}

		// We have all three components of the engine version, so initialize it.
		if( EngineVersionComponents == 3 )
		{
			InitializeEngineVersion();
		}

		bHasCompleteData = true;
	}
	else
	{
		bHasCompleteData = false;
	}
}