using System;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;

namespace AllocsFixes.NetConnections
{
	public class ConsoleOutputSeparator
	{
		public struct NetCommand
		{
			public string command;
			public IConnection client;

			public NetCommand (string _cmd, IConnection _client)
			{
				command = _cmd;
				client = _client;
			}
		}

		private static List<NetCommand> netCommandQueue = new List<NetCommand> ();
		private static bool isCurrentCommandFromClient = false;
		private static int issuerOfCurrentClientCommand = -1;
		private static IConnection issuerOfCurrentCommand;

		public static void C_ExecuteCmdFromClient (ConsoleSdtd console, int _entityId, string _playerName, string _playerID, string _command)
		{
			Log.Out ("Executed command \"" + _command + "\" from player \"" + _playerName + "\"");

			lock (netCommandQueue) {
				isCurrentCommandFromClient = true;
				issuerOfCurrentClientCommand = _entityId;

				string[] array = _command.Split (' ');
				if (array.Length == 0) {
					C_SendResult (console, "*** ERROR: empty command '" + _command + "'");
				} else {
					ConsoleCommand cmd = console.getCommand (_command);
					if (cmd != null) {
						string[] array2 = new string[array.Length - 1];
						for (int i = 1; i < array.Length; i++) {
							array2 [i - 1] = array [i];
						}
						cmd.ExecuteRemote (_playerID, array2);
					} else {
						C_SendResult (console, "*** ERROR: unknown command '" + array [0] + "'");
					}
				}

				isCurrentCommandFromClient = false;
			}

		}

		public static void C_SendResult (ConsoleSdtd console, string _line)
		{
			if (isCurrentCommandFromClient) {
				CommonMappingFunctions.GetConnectionManager ().SendPackage (new NetPackage_ConsoleCmdClient (_line, false), new PackageDestinationSingleEntityID (issuerOfCurrentClientCommand));
			} else {
				if (console.telnetServer != null && issuerOfCurrentCommand != null)
					issuerOfCurrentCommand.SendLine (_line);
				else if (ControlPanel.IsStarted ())
					ControlPanel.AddTextToOutputBuffer (_line);
			}
		}

		public static void C_Run (ConsoleSdtd console)
		{
			if (netCommandQueue.Count > 0) {
				lock (netCommandQueue) {
					issuerOfCurrentCommand = netCommandQueue [0].client;
					try {
						console.ExecuteRemoteCmdInternal (netCommandQueue [0].command, false);
					} catch (Exception e) {
						Log.Out("Exception while executing command: " + e);
					}
					netCommandQueue.RemoveAt (0);
					issuerOfCurrentCommand = null;
				}
			}
		}

		public static void QueueNetCommand (string _line, IConnection _con)
		{
			lock (netCommandQueue) {
				netCommandQueue.Add (new NetCommand (_line, _con));
			}
		}
	}
}
