using System;
using JetBrains.Annotations;
using Utf8Json;

namespace Webserver.WebAPI.APIs.ServerState {
	[UsedImplicitly]
	public class GamePrefs : AbsRestApi {
		private static readonly byte[] keyType = JsonWriter.GetEncodedPropertyNameWithBeginObject ("type");
		private static readonly byte[] keyValue = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("value");
		private static readonly byte[] keyDefault = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("default");

		private int largestBuffer;

		protected override void HandleRestGet (RequestContext _context) {
			PrepareEnvelopedResult (out JsonWriter writer);
			
			writer.EnsureCapacity (largestBuffer);
			writer.WriteBeginObject ();

			bool first = true;
			foreach (EnumGamePrefs stat in EnumUtils.Values<EnumGamePrefs> ()) {
				string name = stat.ToStringCached ();
				global::GamePrefs.EnumType? type = global::GamePrefs.GetPrefType (stat);

				if (name.Contains ("Password", StringComparison.Ordinal)) {
					continue;
				}

				if (!first) {
					writer.WriteValueSeparator ();
				}

				first = false;
				
				writer.WritePropertyName (name);
				
				writer.WriteRaw (keyType);
				writer.WriteString (type.HasValue ? type.Value.ToStringCached () : "noType");
				
				writer.WriteRaw (keyValue);
				switch (type) {
					case global::GamePrefs.EnumType.Int:
						writer.WriteInt32 (global::GamePrefs.GetInt (stat));
						break;
					case global::GamePrefs.EnumType.Float:
						writer.WriteSingle (global::GamePrefs.GetFloat (stat));
						break;
					case global::GamePrefs.EnumType.String:
						writer.WriteString (global::GamePrefs.GetString (stat));
						break;
					case global::GamePrefs.EnumType.Bool:
						writer.WriteBoolean (global::GamePrefs.GetBool (stat));
						break;
					default:
						writer.WriteNull ();
						break;
				}
				
				writer.WriteRaw (keyDefault);
				object defaultValue = global::GamePrefs.GetDefault (stat);
				switch (type) {
					case global::GamePrefs.EnumType.Int:
						if (defaultValue is int defaultInt) {
							writer.WriteInt32 (defaultInt);
						} else {
							writer.WriteNull ();
						}

						break;
					case global::GamePrefs.EnumType.Float:
						if (defaultValue is float defaultFloat) {
							writer.WriteSingle (defaultFloat);
						} else {
							writer.WriteNull ();
						}

						break;
					case global::GamePrefs.EnumType.String:
						if (defaultValue is string defaultString) {
							writer.WriteString (defaultString);
						} else {
							writer.WriteNull ();
						}

						break;
					case global::GamePrefs.EnumType.Bool:
						if (defaultValue is bool defaultBool) {
							writer.WriteBoolean (defaultBool);
						} else {
							writer.WriteNull ();
						}

						break;
					default:
						writer.WriteNull ();
						break;
				}

				writer.WriteEndObject ();
			}
			
			writer.WriteEndObject ();

			int bufferContentSize = writer.CurrentOffset + 128;
			if (bufferContentSize > largestBuffer) {
				largestBuffer = bufferContentSize;
			}
			
			SendEnvelopedResult (_context, ref writer);
		}
	}
}