using Newtonsoft.Json;
using skyscraper5.Mpeg2;
using skyscraper5.Mpeg2.Descriptors;
using skyscraper5.src.InteractionChannel.Model;
using skyscraper5.src.InteractionChannel.Model.Descriptors;
using skyscraper8.InteractionChannel.Model2.Descriptors;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace skyscraper8.InteractionChannel
{
	public class TimJsonRepresentation
	{
		public TimJsonRepresentation() { }

		public TimJsonRepresentation(Tim tim)
		{
			this.Broadcast = tim.Broadcast;
			this.Status = tim.Status;
			this.DescriptorTypes = new byte[tim.Descriptors.Length];
			this.DescriptorsSerialized = new string[tim.Descriptors.Length];
			for (int i = 0; i < tim.Descriptors.Length; i++)
			{
				this.DescriptorTypes[i] = tim.Descriptors[i].GetDescriptorId();
				this.DescriptorsSerialized[i] = JsonConvert.SerializeObject(tim.Descriptors[i], Formatting.Indented);
			}
		}
		
		public Tim ToTim()
		{
			TsDescriptor[] descs = new TsDescriptor[this.DescriptorTypes.Length];
			for (int i = 0; i < this.DescriptorTypes.Length; i++)
			{
				TsDescriptor newChild = null;
				switch (this.DescriptorTypes[i])
				{
					case 0xa0:
						newChild = JsonConvert.DeserializeObject<_0xa0_NetworkLayerInfoDescriptor>(this.DescriptorsSerialized[i]);
						break;
					case 0xa1:
						newChild = JsonConvert.DeserializeObject<_0xa1_CorrectionMessageDescriptor>(this.DescriptorsSerialized[i]);
						break;
					case 0xab:
						newChild = JsonConvert.DeserializeObject<_0xab_ContentionControlDescriptor>(this.DescriptorsSerialized[i]);
						break;
					case 0xac:
						newChild = JsonConvert.DeserializeObject<_0xac_CorrectionControlDescriptor>(this.DescriptorsSerialized[i]);
						break;
					case 0xb7:
						newChild = JsonConvert.DeserializeObject<_0xb7_FramePayloadFormatDescriptor>(this.DescriptorsSerialized[i]);
						break;
					case 0xe1:
						newChild = JsonConvert.DeserializeObject<UserDefinedDescriptor>(this.DescriptorsSerialized[i]);
						break;
					default:
						throw new NotImplementedException(String.Format("Don't know how to deserialize TIM descriptor type _0x{0:X2}", this.DescriptorTypes[i]));
				}
				newChild.Valid = true;
				descs[i] = newChild;
			}
			Tim result = new Tim(Broadcast, Status, descs);
			return result;
		}

		public bool Broadcast { get; set; }
		public byte Status { get; set; }
		public byte[] DescriptorTypes { get; set; }
		public string[] DescriptorsSerialized { get; set; }

		public static TimJsonRepresentation FromTim(Tim tim)
		{
			return new TimJsonRepresentation(tim);
		}

		public static Tim ConvertJsonToTim(string json)
		{
			TimJsonRepresentation representation = JsonConvert.DeserializeObject<TimJsonRepresentation>(json);
			return representation.ToTim();
		}

		public string ToJson()
		{
			return JsonConvert.SerializeObject(this, Formatting.Indented);
		}
	}
}
