// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.CmdPal.Ext.Registry.Constants;
namespace Microsoft.CmdPal.Ext.Registry.Helpers;
///
/// Helper class to easier work with queries
///
internal static partial class QueryHelper
{
///
/// The character to distinguish if the search query contain multiple parts (typically "\\")
///
internal const string QuerySplitCharacter = "\\\\";
///
/// A list that contain short names of all registry base keys
///
private static readonly IReadOnlyDictionary _shortBaseKeys = new Dictionary(6)
{
{ Win32.Registry.ClassesRoot.Name, KeyName.ClassRootShort },
{ Win32.Registry.CurrentConfig.Name, KeyName.CurrentConfigShort },
{ Win32.Registry.CurrentUser.Name, KeyName.CurrentUserShort },
{ Win32.Registry.LocalMachine.Name, KeyName.LocalMachineShort },
{ Win32.Registry.PerformanceData.Name, KeyName.PerformanceDataShort },
{ Win32.Registry.Users.Name, KeyName.UsersShort },
};
[GeneratedRegex(@"/(?<=^(?:[^""]*""[^""]*"")*[^""]*)(?
/// Sanitize the query to avoid issues with the regex
///
/// Query containing front-slash
/// A string replacing all the front-slashes with back-slashes
private static string SanitizeQuery(in string query)
{
var sanitizedQuery = FrontToBackSlashRegex().Replace(query, "\\");
return sanitizedQuery.Replace("\"", string.Empty);
}
///
/// Return the parts of a given query
///
/// The query that could contain parts
/// The key part of the query
/// The value name part of the query
/// when the query search for a key and a value name, otherwise
internal static bool GetQueryParts(in string query, out string queryKey, out string queryValueName)
{
var sanitizedQuery = SanitizeQuery(query);
if (!sanitizedQuery.Contains(QuerySplitCharacter, StringComparison.InvariantCultureIgnoreCase))
{
queryKey = sanitizedQuery;
queryValueName = string.Empty;
return false;
}
var querySplit = sanitizedQuery.Split(QuerySplitCharacter);
queryKey = querySplit.First();
queryValueName = querySplit.Last();
return true;
}
///
/// Return a registry key with a long base key
///
/// A registry key with a short base key
/// A registry key with a long base key
internal static string GetKeyWithLongBaseKey(in string registryKey)
{
foreach (var shortName in _shortBaseKeys)
{
if (!registryKey.StartsWith(shortName.Value, StringComparison.InvariantCultureIgnoreCase))
{
continue;
}
return registryKey.Replace(shortName.Value, shortName.Key, StringComparison.InvariantCultureIgnoreCase);
}
return registryKey;
}
///
/// Return a registry key with a short base key (useful to reduce the text length of a registry key)
///
/// A registry key with a full base key
/// A registry key with a short base key
internal static string GetKeyWithShortBaseKey(in string registryKey)
{
foreach (var shortName in _shortBaseKeys)
{
if (!registryKey.StartsWith(shortName.Key, StringComparison.InvariantCultureIgnoreCase))
{
continue;
}
return registryKey.Replace(shortName.Key, shortName.Value, StringComparison.InvariantCultureIgnoreCase);
}
return registryKey;
}
}