using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace skyscraper8.SatIp.RtspResponses
{
	internal class RtspSetupResponse : RtspResponse
	{
		public RtspSetupResponse(RtspResponseHeader header) : base(header)
		{
		}

		public Socket RtpSocket { get; set; }
		public Socket RtcpSocket { get; set; }

		public uint CSeq
		{
			get
			{
				return uint.Parse(base.args["CSeq"]);
			}
		}

		public uint Session
		{
			get
			{
				string s = base.args["Session"];
				string[] strings = s.Split(';');
				return uint.Parse(strings[0]);
			}
		}

		public uint StreamId
		{
			get
			{
				return uint.Parse(base.args["com.ses.streamID"]);
			}
		}

		private byte exitedThread;
		private CancellationTokenSource rtpCancellation;
		private CancellationTokenSource rtcpCancellation;
		private Thread rtpThread;
		private Thread rtcpThread;
		private bool listenersStarted;
		internal void SetupListeners()
		{
			if (listenersStarted)
				throw new RtspException("Listener already started.");

			if (RtpSocket != null)
			{
				rtpCancellation = new CancellationTokenSource();
			}
			rtcpCancellation = new CancellationTokenSource();

			if (RtpSocket != null)
			{
				Task.Run(async () =>
					{
						byte[] buffer = new byte[2048];

						while (!rtpCancellation.IsCancellationRequested)
						{
							Array.Clear(buffer);
							int result = await RtpSocket.ReceiveAsync(buffer, rtpCancellation.Token);
							OnRtpPacket?.Invoke(buffer, result);
						}

						exitedThread++;
					}
				);
			}

			Task.Run(async () =>
				{
					byte[] buffer = new byte[2048];
					while (!rtcpCancellation.IsCancellationRequested)
					{
						Array.Clear(buffer);
						ValueTask<int> task = RtcpSocket.ReceiveAsync(buffer, rtcpCancellation.Token);
						int taskResult = task.Result;
						OnRtcpPacket?.Invoke(buffer, taskResult);
					}

					exitedThread++;
				}
			);

			listenersStarted = true;
		}
		

		internal void InvokeCancellationTokens()
		{
			rtpCancellation?.Cancel();
			rtcpCancellation?.Cancel();
		}

		public event OnRtpPacket OnRtpPacket;
		public event OnRtpPacket OnRtcpPacket;
	}

	public delegate void OnRtpPacket(byte[] data, int length);
}
