using System.Collections.Generic;
using JetBrains.Annotations;
using Utf8Json;

namespace Webserver.WebAPI.APIs {
	[UsedImplicitly]
	public class LogApi : AbsRestApi {
		private const int maxCount = 1000;

		private static readonly byte[] jsonKeyEntries = JsonWriter.GetEncodedPropertyNameWithBeginObject ("entries");
		private static readonly byte[] jsonKeyFirstLine = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("firstLine");
		private static readonly byte[] jsonKeyLastLine = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("lastLine");

		private static readonly byte[] jsonMsgKey = JsonWriter.GetEncodedPropertyNameWithBeginObject ("msg");
		private static readonly byte[] jsonTypeKey = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("type");
		private static readonly byte[] jsonTraceKey = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("trace");
		private static readonly byte[] jsonIsotimeKey = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("isotime");
		private static readonly byte[] jsonUptimeKey = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator ("uptime");

		public LogApi () : base ("Log") {
		}

		protected override void HandleRestGet (RequestContext _context) {
			if (_context.Request.QueryString ["count"] == null || !int.TryParse (_context.Request.QueryString ["count"], out int count)) {
				count = 50;
			}

			if (count == 0) {
				count = 1;
			}

			if (count > maxCount) {
				count = maxCount;
			}

			if (count < -maxCount) {
				count = -maxCount;
			}

			if (_context.Request.QueryString ["firstLine"] == null || !int.TryParse (_context.Request.QueryString ["firstLine"], out int firstLine)) {
				firstLine = count > 0 ? LogBuffer.Instance.OldestLine : LogBuffer.Instance.LatestLine;
			}
			
			PrepareEnvelopedResult (out JsonWriter writer);
			
			writer.WriteRaw (jsonKeyEntries);
			
			List<LogBuffer.LogEntry> logEntries = LogBuffer.Instance.GetRange (ref firstLine, count, out int lastLine);

			writer.WriteBeginArray ();

			for (int i = 0; i < logEntries.Count; i++) {
				LogBuffer.LogEntry logEntry = logEntries [i];
				
				if (i > 0) {
					writer.WriteValueSeparator ();
				}

				writer.WriteRaw (jsonMsgKey);
				writer.WriteString (logEntry.Message);

				writer.WriteRaw (jsonTypeKey);
				writer.WriteString (logEntry.Type.ToStringCached ());

				writer.WriteRaw (jsonTraceKey);
				writer.WriteString (logEntry.Trace);

				writer.WriteRaw (jsonIsotimeKey);
				writer.WriteString (logEntry.IsoTime);

				writer.WriteRaw (jsonUptimeKey);
				writer.WriteString (logEntry.Uptime.ToString ());

				writer.WriteEndObject ();
			}

			writer.WriteEndArray ();

			writer.WriteRaw (jsonKeyFirstLine);
			writer.WriteInt32 (firstLine);
			
			writer.WriteRaw (jsonKeyLastLine);
			writer.WriteInt32 (lastLine);
			
			writer.WriteEndObject ();

			SendEnvelopedResult (_context, ref writer);
		}
	}
}