/ src / modules / cmdpal / ext / Microsoft.CmdPal.Ext.TimeDate / Helpers / TimeDateCalculator.cs
TimeDateCalculator.cs
  1  // Copyright (c) Microsoft Corporation
  2  // The Microsoft Corporation licenses this file to you under the MIT license.
  3  // See the LICENSE file in the project root for more information.
  4  
  5  using System;
  6  using System.Collections.Generic;
  7  using System.Linq;
  8  using System.Text.RegularExpressions;
  9  using Microsoft.CommandPalette.Extensions.Toolkit;
 10  
 11  namespace Microsoft.CmdPal.Ext.TimeDate.Helpers;
 12  
 13  public sealed partial class TimeDateCalculator
 14  {
 15      /// <summary>
 16      /// Var that holds the delimiter between format and date
 17      /// </summary>
 18      private const string InputDelimiter = "::";
 19  
 20      /// <summary>
 21      /// Searches for results
 22      /// </summary>
 23      /// <param name="query">Search query object</param>
 24      /// <returns>List of Wox <see cref="Result"/>s.</returns>
 25      public static List<ListItem> ExecuteSearch(ISettingsInterface settings, string query)
 26      {
 27          var isEmptySearchInput = string.IsNullOrWhiteSpace(query);
 28          List<AvailableResult> availableFormats = new List<AvailableResult>();
 29          List<ListItem> results = new List<ListItem>();
 30  
 31          // currently, all of the search in V2 is keyword search.
 32          var isKeywordSearch = true;
 33  
 34          // Last input parsing error
 35          var lastInputParsingErrorMsg = string.Empty;
 36  
 37          // Switch search type
 38          if (isEmptySearchInput || (!isKeywordSearch))
 39          {
 40              // Return all results for system time/date on empty keyword search
 41              // or only time, date and now results for system time on global queries if the corresponding setting is enabled
 42              availableFormats.AddRange(AvailableResultsList.GetList(isKeywordSearch, settings));
 43          }
 44          else if (Regex.IsMatch(query, @".+" + Regex.Escape(InputDelimiter) + @".+"))
 45          {
 46              // Search for specified format with specified time/date value
 47              var userInput = query.Split(InputDelimiter);
 48              if (TimeAndDateHelper.ParseStringAsDateTime(userInput[1], out DateTime timestamp, out lastInputParsingErrorMsg))
 49              {
 50                  availableFormats.AddRange(AvailableResultsList.GetList(isKeywordSearch, settings, null, null, timestamp));
 51                  query = userInput[0];
 52              }
 53          }
 54          else if (TimeAndDateHelper.ParseStringAsDateTime(query, out DateTime timestamp, out lastInputParsingErrorMsg))
 55          {
 56              // Return all formats for specified time/date value
 57              availableFormats.AddRange(AvailableResultsList.GetList(isKeywordSearch, settings, null, null, timestamp));
 58              query = string.Empty;
 59          }
 60          else
 61          {
 62              // Search for specified format with system time/date (All other cases)
 63              availableFormats.AddRange(AvailableResultsList.GetList(isKeywordSearch, settings));
 64          }
 65  
 66          // Check searchTerm after getting results to select type of result list
 67          if (string.IsNullOrEmpty(query))
 68          {
 69              // Generate list with all results
 70              foreach (var f in availableFormats)
 71              {
 72                  results.Add(f.ToListItem());
 73              }
 74          }
 75          else
 76          {
 77              List<(int Score, AvailableResult Item)> itemScores = [];
 78  
 79              // Generate filtered list of results
 80              foreach (var f in availableFormats)
 81              {
 82                  var score = f.Score(query, f.Label, f.AlternativeSearchTag);
 83                  if (score > 0)
 84                  {
 85                      itemScores.Add((score, f));
 86                  }
 87              }
 88  
 89              results = itemScores
 90                          .OrderByDescending(s => s.Score)
 91                          .Select(s => s.Item.ToListItem())
 92                          .ToList();
 93          }
 94  
 95          if (results.Count == 0)
 96          {
 97              var er = ResultHelper.CreateInvalidInputErrorResult();
 98              if (!string.IsNullOrEmpty(lastInputParsingErrorMsg))
 99              {
100                  er.Details = new Details() { Body = lastInputParsingErrorMsg };
101              }
102  
103              results.Add(er);
104          }
105  
106          return results;
107      }
108  }