using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using LuhnNet;
using Newtonsoft.Json; //Do not remove - Required for JObject
using Newtonsoft.Json.Linq;
using Shinydocs.CognitiveToolkit.Core.Tools.ScrollTools.RunScript;
using Shinydocs.CognitiveToolkit.Scripting;
using Shinydocs.CognitiveToolkit.Utilities; //Do not remove - Required for JObject

public class NormalizeExtension : IScript
{
	private static string Version = "2.6.0";
	// ScriptLogger allows you to log to the same index as the rest of the cognitive toolkit. 
	// See https://github.com/serilog/serilog/wiki/Writing-Log-Events for message formatting information
	private readonly ScriptLogger _log = new ScriptLogger();

	private string[] _fieldsToReturn = { "id", "extension" };
	private string _indexName;
	private string _query;
	private string _serverUrl;
	private int _threads;
	private int _nodesPerRequest;
	private RunScriptDocumentUpdater _documentUpdater;

	/// <summary>
	/// SetUp Called before executing run
	/// </summary>
	/// <param name="arguments">Array of command line arguments passed in, excluding the Script File Path ("-p") and Script Class Name ("-c") parameters used by the RunScript tool</param>
	public void SetUp(string[] arguments)
	{
		_log.Information(string.Format("Using version {0}", Version));
		Console.WriteLine(string.Format("Using version {0}", Version));
		try
		{
			Dictionary<string, string> options;

			// OptionsParser will parse an array of arguments into a dictionary of flags and values
			if (OptionsParser.TryParse(arguments, out options))
			{
				OptionsParser.ParseStandardOptions(options, out _serverUrl, out _indexName, out _threads, out _nodesPerRequest);
				OptionsParser.ParseQueryOption(options, out _query);

				_documentUpdater = new RunScriptDocumentUpdater(_serverUrl, _indexName, _fieldsToReturn, _nodesPerRequest, _threads);
				_log.Information(string.Format("Tool setup method -q = {0}  -u = {1}  " +
											   "-i = {2} ", _query, _serverUrl, _indexName));
			}
			else
			{
				throw new ArgumentException("Failed to parse arguments. Tool requires exactly the following parameters -q (Query or Path to QueryFile) -u (Index Server Url) -i (IndexName).");
			}
		}
		catch (Exception ex)
		{
			Console.WriteLine("Tool requires exactly the following parameters -q (Query or Path to QueryFile) -u (Index Server Url) -i (IndexName). " + ex.Message);
			throw;
		}
	}

	public void Run()
	{
		_documentUpdater.Update(_query, LowerCaseAndNoLeadingPeriod);
	}

	public Dictionary<string, object> LowerCaseAndNoLeadingPeriod(JObject document)
	{
		var extension = document["extension"].ToString();
		if (extension.StartsWith(".")) extension = extension.Substring(1);
		document["extension"] = extension.ToLower();

		return new Dictionary<string, object>() { {"extension", document["extension"]} };

	}

	public void TearDown()
	{
	}
}