From ddd94b364186084171ef0e9c5109771233352cc0 Mon Sep 17 00:00:00 2001
From: Starbeamrainbowlabs <sbrl@starbeamrainbowlabs.com>
Date: Tue, 11 Sep 2018 14:47:24 +0100
Subject: [PATCH] Get adding to a search index working

---
 SearchBox-CLI/Program.cs   | 14 +++++++++++---
 SearchBox/DocumentMeta.cs  | 15 +++++++++++++--
 SearchBox/IdMap.cs         | 18 ++++++++++++++++++
 SearchBox/InvertedIndex.cs |  3 ++-
 SearchBox/SearchBox.cs     |  7 ++++---
 5 files changed, 48 insertions(+), 9 deletions(-)

diff --git a/SearchBox-CLI/Program.cs b/SearchBox-CLI/Program.cs
index 4ab506e..f56688d 100644
--- a/SearchBox-CLI/Program.cs
+++ b/SearchBox-CLI/Program.cs
@@ -38,8 +38,12 @@ namespace SearchBoxCLI
 			List<string> extras = new List<string>();
 			for (int i = 0; i < args.Length; i++)
 			{
-				switch (args[i].TrimStart("-".ToCharArray()))
-				{
+				if (!args[i].StartsWith("-")) {
+					extras.Add(args[i]);
+					continue;
+				}
+
+				switch (args[i].TrimStart("-".ToCharArray())) {
 					case "s":
 					case "source":
 						string sourceFilename = args[++i];
@@ -79,7 +83,7 @@ namespace SearchBoxCLI
 			}
 			if (extras.Count < 1) return HandleHelp();
 			string modeText = extras.First(); extras.RemoveAt(0);
-			Mode = (OperatingModes)Enum.Parse(typeof(OperatingModes), modeText);
+			Mode = (OperatingModes)Enum.Parse(typeof(OperatingModes), modeText, true);
 
 			switch (Mode) {
 				case OperatingModes.Index: return HandleIndex();
@@ -126,6 +130,10 @@ namespace SearchBoxCLI
 				Console.Error.WriteLine("Error: The document name must be specified when reading from stdin!");
 				return 1;
 			}
+			if (SearchIndexFilepath == string.Empty) {
+				Console.Error.WriteLine("Error: No search index file path specified.");
+				return 1;
+			}
 
 			// --------------------------------------
 
diff --git a/SearchBox/DocumentMeta.cs b/SearchBox/DocumentMeta.cs
index 033e320..f2d74f9 100644
--- a/SearchBox/DocumentMeta.cs
+++ b/SearchBox/DocumentMeta.cs
@@ -6,12 +6,13 @@ namespace LibSearchBox
 	public class DocumentMeta
 	{
 		public string Title { get; set; }
-		public List<string> Tags { get; private set; }
+		public List<string> Tags { get; private set; } = new List<string>();
 
 		public DocumentMeta(string inTitle, IEnumerable<string> inTags)
 		{
 			Title = inTitle;
-			Tags = new List<string>(inTags);
+			if (inTags != null)
+				Tags.AddRange(inTags);
 		}
 
 		public void ReplaceTags(IEnumerable<string> newTags)
@@ -19,5 +20,15 @@ namespace LibSearchBox
 			Tags.Clear();
 			Tags.AddRange(newTags);
 		}
+
+
+		#region Overrides
+
+		public override string ToString()
+		{
+			return $"[DocumentMeta Title={Title}, Tags={string.Join(",", Tags)}]";
+		}
+
+		#endregion
 	}
 }
diff --git a/SearchBox/IdMap.cs b/SearchBox/IdMap.cs
index adeb614..958157f 100644
--- a/SearchBox/IdMap.cs
+++ b/SearchBox/IdMap.cs
@@ -1,17 +1,35 @@
 ﻿using System;
 using System.Collections.Generic;
 using System.Text;
+using Newtonsoft.Json;
 using Stackoverflow.Utilities;
 
 namespace LibSearchBox
 {
 	public class IdNotFoundException : Exception { public IdNotFoundException(string message) : base(message) {  } }
 
+	[JsonObject(MemberSerialization.OptIn)]
 	public class IdMap
 	{
+		[JsonProperty]
 		private int nextId = 0;
 		public BiDictionary<int, string> map = new BiDictionary<int, string>();
 
+		[JsonProperty]
+		public Dictionary<int, string> Map {
+			get {
+				Dictionary<int, string> result = new Dictionary<int, string>();
+				foreach (BiDictionary<int, string>.Pair pair in map)
+					result.Add(pair.First, pair.Second);
+				return result;
+			}
+			set {
+				map.Clear();
+				foreach (KeyValuePair<int, string> pair in value)
+					map.Add(pair.Key, pair.Value);
+			}
+		}
+
 		public IdMap()
 		{
 		}
diff --git a/SearchBox/InvertedIndex.cs b/SearchBox/InvertedIndex.cs
index a46f4fe..195dddb 100644
--- a/SearchBox/InvertedIndex.cs
+++ b/SearchBox/InvertedIndex.cs
@@ -6,7 +6,8 @@ namespace LibSearchBox
 {
 	public class InvertedIndex
 	{
-		private ConcurrentDictionary<string, ConcurrentDictionary<int, List<int>>> invertedIndex = new ConcurrentDictionary<string, ConcurrentDictionary<int, List<int>>>();
+		// Gotta be public to allow Newtonsoft.JSON to do it's job. Don't interact with it directly!
+		public ConcurrentDictionary<string, ConcurrentDictionary<int, List<int>>> invertedIndex = new ConcurrentDictionary<string, ConcurrentDictionary<int, List<int>>>();
 
 		public InvertedIndex()
 		{
diff --git a/SearchBox/SearchBox.cs b/SearchBox/SearchBox.cs
index ddc9d38..c256d31 100644
--- a/SearchBox/SearchBox.cs
+++ b/SearchBox/SearchBox.cs
@@ -1,6 +1,7 @@
 ﻿using System;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
+using Newtonsoft.Json;
 
 namespace LibSearchBox
 {
@@ -8,9 +9,9 @@ namespace LibSearchBox
 
 	public class SearchBox
 	{
-		private IdMap idMap = new IdMap();
-		private InvertedIndex index = new InvertedIndex();
-		private ConcurrentDictionary<int, DocumentMeta> metaTable = new ConcurrentDictionary<int, DocumentMeta>();
+		public IdMap idMap = new IdMap();
+		public InvertedIndex index = new InvertedIndex();
+		public ConcurrentDictionary<int, DocumentMeta> metaTable = new ConcurrentDictionary<int, DocumentMeta>();
 
 		public SearchBox()
 		{
