commit 9cc42e604150e61ef0edb679db4b80a07592f3e4
Author: Eliška Mourycová <eliska.mourycova@seznam.cz>
Date:   Sat Jun 12 19:50:51 2021 +0200

    Re #9055. Fixed admin commands related bug + refactor + documentation comments

diff --git a/Server/ServerApp/Connection/ConnectionListener.cs b/Server/ServerApp/Connection/ConnectionListener.cs
index 71161f2..52178f6 100644
--- a/Server/ServerApp/Connection/ConnectionListener.cs
+++ b/Server/ServerApp/Connection/ConnectionListener.cs
@@ -154,7 +154,10 @@ namespace ServerApp.Connection
 			logger.Debug("At the end of HandleRequest");
 		}
 
-
+		/// <summary>
+		/// The callnack method triggered when client request received
+		/// </summary>
+		/// <param name="result"></param>
 		private void ListenerCallback(IAsyncResult result)
 		{
 			logger.Debug("in ListenerCallback");
@@ -239,7 +242,11 @@ namespace ServerApp.Connection
 
 		}
 
-
+		/// <summary>
+		/// Constructs the response for GET requests
+		/// </summary>
+		/// <param name="requestString">The whole string received with the GET request</param>
+		/// <returns>The response string, empty if client's request doesn't follow protocol</returns>
 		private string ConstructGETResponse(string requestString)
 		{
 			//Console.WriteLine("Constructiing a response for GET request.");
@@ -291,6 +298,11 @@ namespace ServerApp.Connection
 
 		}
 
+		/// <summary>
+		/// Constructs the response for POST requests
+		/// </summary>
+		/// <param name="requestString">The whole string received with the POST request</param>
+		/// <returns>The response string, empty if client's request doesn't follow protocol</returns>
 		private string ConstructPOSTResponse(string requestString)
 		{
 			logger.Info("Constructing a response for POST request.");
@@ -333,7 +345,10 @@ namespace ServerApp.Connection
 
 		}
 
-
+		/// <summary>
+		/// Gets the IPv4 IP of the machine
+		/// </summary>
+		/// <returns>The IP as a string</returns>
 		private string GetLocalIPAddress()
 		{
 			var host = Dns.GetHostEntry(Dns.GetHostName());
diff --git a/Server/ServerApp/Program.cs b/Server/ServerApp/Program.cs
index 33d1605..63deb0a 100644
--- a/Server/ServerApp/Program.cs
+++ b/Server/ServerApp/Program.cs
@@ -16,7 +16,7 @@ using System.Threading;
 namespace ServerApp
 {
 
-	class Config // TBD where this should go
+	class Config
 	{
 		public string DataWebsite { get; set; }
 		public string DownloadedFilesNaming { get; set; }
@@ -28,11 +28,6 @@ namespace ServerApp
     public class Program
     {
 
-		//public void NotifyUserMessage(string message)
-		//{
-		//	Console.WriteLine("Received user message: " + message);
-		//}
-
         static void Main(string[] args)
         {
             // setup logging service
@@ -42,6 +37,7 @@ namespace ServerApp
 			Config config = FillConfigInfo(args);
 			if (config == null)
 			{
+				Console.WriteLine("Configuration file parsing failed. Abort.");
 				Console.ReadLine();
 				return;
 			}
@@ -49,8 +45,8 @@ namespace ServerApp
 			// data download test
 			DataDownloader dd = DataDownloadAndRetrievalTest(config);
 
-			WeatherAsStringTest(dd);
-			Console.ReadLine();
+			//WeatherAsStringTest(dd);
+			//Console.ReadLine();
 
 			// xml building test
 			//XMLTest();
@@ -73,10 +69,11 @@ namespace ServerApp
 			Thread inputThread = new Thread(ca.AcceptCommand);
 			inputThread.Start();
 
+
 			// connection test
 			ConnectionTest(controller, config);
 
-			Console.ReadLine();
+			//Console.ReadLine();
         }
 
 
@@ -202,7 +199,7 @@ namespace ServerApp
 			Console.WriteLine("Parsing configuration file...");
 			
 			if (args.Length != 1)
-				Console.WriteLine("Wrong usage of parameters, pass the path to a config file."); // todo better explanation?
+				Console.WriteLine("Wrong usage of parameters, pass only the path to a config file.");
 
 			string fullPathConfig = Path.GetFullPath(args[0]);
 			string[] lines = null;
@@ -248,6 +245,16 @@ namespace ServerApp
 				}
 			}
 
+			int parsedPort;
+
+			bool success = int.TryParse(extractedConfigInfo.Port, out parsedPort);
+			if (!success)
+			{
+				Console.WriteLine("Configured port " + extractedConfigInfo.Port + " is not an integer number! Abort.");
+				return null;
+			}
+				
+
 			return extractedConfigInfo;
 		}
     }
diff --git a/Server/ServerApp/Properties/launchSettings.json b/Server/ServerApp/Properties/launchSettings.json
index c0762b1..c5b461c 100644
--- a/Server/ServerApp/Properties/launchSettings.json
+++ b/Server/ServerApp/Properties/launchSettings.json
@@ -2,7 +2,7 @@
   "profiles": {
     "ServerApp": {
       "commandName": "Project",
-      "commandLineArgs": ".\\server_config"
+      "commandLineArgs": "C:\\Users\\elisk\\Documents\\aswi2021tri-musketyri\\Server\\ServerApp\\server_config"
     }
   }
 }
\ No newline at end of file
diff --git a/Server/ServerApp/User/Command.cs b/Server/ServerApp/User/Command.cs
index 67e5577..3440f79 100644
--- a/Server/ServerApp/User/Command.cs
+++ b/Server/ServerApp/User/Command.cs
@@ -1,4 +1,8 @@
-﻿using System;
+﻿//
+// Author: Eliska Mourycova
+//
+
+using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
@@ -6,12 +10,27 @@ using System.Threading.Tasks;
 
 namespace ServerApp.User
 {
-
+	/// <summary>
+	/// This class represents a command input by the admin
+	/// </summary>
 	public class Command
 	{
+		/// <summary>
+		/// The whole string input
+		/// </summary>
 		public string WholeCommand { get; set; }
+
+		/// <summary>
+		/// The main part of the command
+		/// </summary>
 		public string MainCommand { get; set; }
+
+		/// <summary>
+		/// The flags and data associated with the command
+		/// </summary>
 		public Dictionary<string, List<string>> FlagsAndData { get; }
+
+		// the last flag used
 		private string lastFlag;
 
 		public Command()
@@ -21,15 +40,24 @@ namespace ServerApp.User
 			lastFlag = "";
 		}
 
+		/// <summary>
+		/// Adds a flag to the dictionary
+		/// </summary>
+		/// <param name="flag">The flag to add</param>
 		public void AddFlag(string flag)
 		{
 			FlagsAndData.Add(flag, new List<string>());
 			lastFlag = flag;
 		}
 
+		/// <summary>
+		/// Adds data after a flag
+		/// </summary>
+		/// <param name="data">The data to add</param>
 		public void AddData(string data)
 		{
-			FlagsAndData[lastFlag].Add(data);
+			if(FlagsAndData.ContainsKey(lastFlag))
+				FlagsAndData[lastFlag].Add(data);
 		}
 	}
 }
diff --git a/Server/ServerApp/User/CommandsAcceptor.cs b/Server/ServerApp/User/CommandsAcceptor.cs
index 640c456..ba0c7c8 100644
--- a/Server/ServerApp/User/CommandsAcceptor.cs
+++ b/Server/ServerApp/User/CommandsAcceptor.cs
@@ -13,10 +13,15 @@ using System.Threading.Tasks;
 namespace ServerApp.User
 {
 	
-
+	/// <summary>
+	/// This class tkes care of parsing and executing admin commands
+	/// </summary>
 	public class CommandsAcceptor
 	{
+		// the DataDownloader instance
 		private DataDownloader dd;
+
+		// the predictor instance
 		private IPredictionController model;
 
 		public CommandsAcceptor(DataDownloader dd, IPredictionController controller)
@@ -25,6 +30,9 @@ namespace ServerApp.User
 			this.model = controller;
 		}
 
+		/// <summary>
+		/// Prints a prompt and waits for input
+		/// </summary>
 		public void AcceptCommand()
 		{
 			while (true) {
@@ -35,12 +43,16 @@ namespace ServerApp.User
 					Console.WriteLine("received admin command: " + command);
 					Command c = ParseString(command);
 					CheckCommand(c);
-					//Program.NotifyUserMessage(command);
 				}
 
 			}
 		}
 
+		/// <summary>
+		/// Parses the input string
+		/// </summary>
+		/// <param name="str">The whole string typed in by the user</param>
+		/// <returns>A new instance of the Command class</returns>
 		private Command ParseString(string str)
 		{
 
@@ -67,6 +79,10 @@ namespace ServerApp.User
 			return command;
 		}
 
+		/// <summary>
+		/// Checks the comamnd and decides what to do according to the main command
+		/// </summary>
+		/// <param name="c">The command</param>
 		private void CheckCommand(Command c)
 		{
 
@@ -87,11 +103,19 @@ namespace ServerApp.User
 			}
 		}
 
+		/// <summary>
+		/// Prints to the console, that the given command is unknown
+		/// </summary>
+		/// <param name="command">The input command</param>
 		private void PrintUnknown(string command)
 		{
 			Console.WriteLine("Unknown command: " + command);
 		}
 
+		/// <summary>
+		/// Handles the command linked to data listing and downloading
+		/// </summary>
+		/// <param name="c">The command</param>
 		private void HandleDataCommand(Command c)
 		{
 			// data -list
@@ -151,8 +175,17 @@ namespace ServerApp.User
 				
 				
 			}
+			else
+			{
+				PrintUnknown(c.WholeCommand);
+				HandleHelpCommand(c);
+			}
 		}
 
+		/// <summary>
+		/// Handles the command linked to predictor training, rollback and files listing
+		/// </summary>
+		/// <param name="c">The command</param>
 		private void HandleModelCommand(Command c)
 		{
 			// TODO:
@@ -193,12 +226,21 @@ namespace ServerApp.User
 						break;
 				}
 			}
+			else
+			{
+				PrintUnknown(c.WholeCommand);
+				HandleHelpCommand(c);
+			}
 
 
 			//model.Rollback() // 0 -ok, 1 nejde, 2 - error (kdyz nekdo smaze soubor config)
 			//model.GetDataFileNames();
 		}
 
+		/// <summary>
+		/// Prints help to the console
+		/// </summary>
+		/// <param name="c"></param>
 		private void HandleHelpCommand(Command c)
 		{
 			Console.WriteLine("List of available commands and their description: ");
@@ -223,9 +265,5 @@ namespace ServerApp.User
 			Console.WriteLine("      Example: model -rollback");
 		}
 
-		private void PrintUsage(Command c)
-		{
-			
-		}
 	}
 }
