using Console.Waterworks.Core.Models; using Console.Waterworks.Core.Specialists; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; namespace Console.Waterworks.Core.Assistants { class CommandsAssistant { internal bool ValidateClass(Command command, Dictionary>> commandLibraries) => (commandLibraries.ContainsKey(command.ClassName)) ? true : false; internal bool ValidateCommand(Command command, Dictionary>> commandLibraries) { var methodDict = commandLibraries[command.ClassName]; return (methodDict.ContainsKey(command.Name)) ? true : false; } internal string ExecuteBadCommandProcedure(Command command, ConsoleIOSpecialist consoleSpec) { consoleSpec.WriteErrorSuffix(); return $"The command \'{command.Name}\' is not recognised."; } internal bool ValidateParamArguments(Command command, List paramInfoList) { var requiredParams = paramInfoList.Where(p => p.IsOptional == false); var optionalParams = paramInfoList.Where(p => p.IsOptional == true); int requiredCount = requiredParams.Count(); int optionalCount = optionalParams.Count(); int providedCount = command.Arguments.Count(); return (requiredCount > providedCount) ? false : true; } internal string ExecuteMissingArgumentProcedure(Command command, List paramInfoList, ConsoleIOSpecialist consoleSpec) { var requiredParams = paramInfoList.Where(p => p.IsOptional == false); var optionalParams = paramInfoList.Where(p => p.IsOptional == true); int requiredCount = requiredParams.Count(); int optionalCount = optionalParams.Count(); int providedCount = command.Arguments.Count(); return $"Missing required argument. {requiredCount} required, {optionalCount} optional, {providedCount} provided."; } internal List GetParametreValueList(Command command, List paramInfoList) { var methodParameterValueList = new List(); if (paramInfoList.Count() > 0) { foreach (var param in paramInfoList) { methodParameterValueList.Add(param.DefaultValue); } for (int i = 0; i < command.Arguments.Count(); i++) { var methodParam = paramInfoList.ElementAt(i); var typeRequired = methodParam.ParameterType; object value = null; try { value = CoercionSpecialist.CoerceArgument(typeRequired, command.Arguments.ElementAt(i)); methodParameterValueList.RemoveAt(i); methodParameterValueList.Insert(i, value); } catch (ArgumentException ex) { string message = $"The value passed for argument '{methodParam.Name}' cannot be parsed to type '{typeRequired.Name}'"; // The exception message is being used instead, for now. throw new ArgumentException(ex.Message); } } } return methodParameterValueList; } internal Type BuildCommandLibraryClass(Command command, string commandsNamespace) { Assembly programAssembly = Assembly.GetEntryAssembly(); Type commandLibraryClass = programAssembly.GetType($"{commandsNamespace}.{command.ClassName}"); return commandLibraryClass; } internal string InvokeCommand(Command command, Type typeInfo, object[] inputArguments) { try { return typeInfo.GetMethod(command.Name).Invoke(command.Name, inputArguments).ToString(); } catch (TargetInvocationException ex) { throw ex.InnerException; } } internal object[] GetInputArguments(List methodParametreValueList) { object[] inputArguments = null; if (methodParametreValueList.Count > 0) inputArguments = methodParametreValueList.ToArray(); return inputArguments; } } }