using System;
using System.IO;
using System.Net;
using System.Text;

namespace MTA_SDK;

public class MTA
{
	private string _Host = "localhost";

	private int _Port = 22005;

	private string _Username = "";

	private string _Password = "";

	private bool _ReconnectOnFailure = true;

	public MTA()
	{
	}

	public MTA(string host)
	{
		_Host = host;
	}

	public MTA(string host, int port)
	{
		_Host = host;
		_Port = port;
	}

	public MTA(string host, int port, string username, string password)
	{
		_Host = host;
		_Port = port;
		_Username = username;
		_Password = password;
	}

	public string CallFunction(string resourceName, string functionName, MTA_LuaArgs args)
	{
		string json = args.ConvertToJSONString();
		try
		{
			string url = "http://" + _Host + ":" + _Port + "/" + resourceName + "/call/" + functionName;
			return DoPOSTRequest(url, json);
		}
		catch (WebException ex)
		{
			string text = "The remote server returned an error: (401) Unauthorized.";
			if (ex.Message == text)
			{
				if (_ReconnectOnFailure)
				{
					_ReconnectOnFailure = false;
					return DoPOSTRequest(ex.Response.ResponseUri.AbsoluteUri, json);
				}
				_ReconnectOnFailure = true;
				throw new MTARequestException(ex.Message, ex.InnerException, WebExceptionStatus.ConnectFailure, ex.Response);
			}
			throw new MTARequestException(ex.Message, ex.InnerException, WebExceptionStatus.ConnectFailure, ex.Response);
		}
	}

	private string DoPOSTRequest(string url, string json)
	{
		try
		{
			HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
			httpWebRequest.Method = "POST";
			httpWebRequest.AllowAutoRedirect = true;
			if (!string.IsNullOrEmpty(_Username) && !string.IsNullOrEmpty(_Password))
			{
				byte[] bytes = new UTF8Encoding().GetBytes(_Username + ":" + _Password);
				httpWebRequest.Headers["Authorization"] = "Basic " + Convert.ToBase64String(bytes);
			}
			httpWebRequest.ContentType = "application/x-www-form-urlencoded";
			httpWebRequest.Timeout = 3500;
			StreamWriter streamWriter = new StreamWriter(httpWebRequest.GetRequestStream());
			streamWriter.Write(json);
			streamWriter.Close();
			WebResponse response = httpWebRequest.GetResponse();
			StreamReader streamReader = new StreamReader(response.GetResponseStream());
			string text = streamReader.ReadToEnd();
			streamReader.Close();
			streamReader.Dispose();
			streamWriter.Dispose();
			if (text.StartsWith("error"))
			{
				throw new MTARequestException(text);
			}
			return text;
		}
		catch (WebException ex)
		{
			if (_ReconnectOnFailure)
			{
				throw new WebException(ex.Message, ex.InnerException, WebExceptionStatus.ConnectFailure, ex.Response);
			}
			string text2 = "";
			bool flag = string.IsNullOrEmpty(_Username);
			bool flag2 = string.IsNullOrEmpty(_Password);
			text2 = ((!flag && !flag2) ? "Login or Password are incorrect." : ((!flag && flag2) ? "Password is required." : ((!flag || flag2) ? "Login and Password are required." : "Login is required.")));
			throw new MTARequestException("Access denied. " + text2, ex.InnerException, WebExceptionStatus.ConnectFailure, ex.Response);
		}
	}
}
