using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using skyscraper5.Ietf.Rfc971;
using skyscraper5.src.Skyscraper.Scraper;

namespace skyscraper5.Skyscraper.Net
{
    public class IpTrafficInfo
    {
		internal static IpTrafficInfo FromInternetHeader(InternetHeader ih)
        {
            IpTrafficInfo child = new IpTrafficInfo();
            child.Source = ih.SourceAddress;
            child.Target = ih.DestinationAddress;
            child.Protocol = ih.Protocol;
            return child;
        }

		internal static IpTrafficInfo FromIPAddresses(IPAddress source, IPAddress destination, byte protocol)
		{
			IpTrafficInfo child = new IpTrafficInfo();
			child.Source = source;
			child.Target = destination;
			child.Protocol = protocol;
			return child;
		}

        public IPAddress Source { get; set; }
        public IPAddress Target { get; set; }

        public byte Protocol { get; set; }
		public string SourceName { get; set; }
		public string TargetName { get; set; }

		public bool Equals(IpTrafficInfo other)
        {
            return Equals(Source, other.Source) && Equals(Target, other.Target) && Protocol == other.Protocol;
        }

        public override bool Equals(object obj)
        {
            return obj is IpTrafficInfo other && Equals(other);
        }

        public override int GetHashCode()
        {
            return HashCode.Combine(Source, Target, Protocol);
        }

        public static string GetProtocolName(byte Protocol)
        {
            switch (Protocol)
            {
                case 0: return "HOPOPT";
                case 1: return "ICMP";
                case 2: return "IGMP";
                case 4: return "IP-in-IP!";
                case 6: return "TCP";
                case 17: return "UDP";
                case 27: return "RDP";      /** check **/
                case 41: return "IPv6!";
                case 47: return "GRE!";
                case 50: return "ESP";
                case 58: return "ICMPv6";
                case 83: return "VINES";
                case 88: return "EIGRP";
                case 89: return "OSPF";
                case 103: return "PIM";
                case 112: return "VRRP";
                case 115: return "L2TP";
                case 129: return "IPLT";
				case 132: return "SCTP";
                case 139: return "HIP";
                case 253: return "RFC3692";
                case 254: return "RFC3692";
                default:
                    if (Protocol >= 145)
                        return String.Format("Unassigned Protocol {0}", Protocol);
                    return String.Format("Unknown Protocol {0}", Protocol);
            }
        }

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            if (!string.IsNullOrEmpty(SourceName))
                sb.Append(SourceName);
            else
                sb.Append(Source.ToString());

            sb.Append(" -> ");

            if (!string.IsNullOrEmpty(TargetName))
                sb.Append(TargetName);
            else
                sb.Append(Target.ToString());

            sb.Append(" (");
            sb.Append(GetProtocolName(Protocol));
            sb.Append(")");
            return sb.ToString();
        }
        
        public string RenderSource()
        {
            return string.IsNullOrEmpty(SourceName) ? Source.ToString() : SourceName;
        }

        public string RenderTarget()
        {
            return string.IsNullOrEmpty(TargetName) ? Target.ToString() : TargetName;
        }
	}
}
