using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using Microsoft.Phone.Info;

namespace Syslog
{
    public class SyslogClient
    {
        public enum Severity
        {
            Emergency= 0,
            Alert=1, 
            Critical=2, 
            Error=3, 
            Warning=4, 
            Notice=5, 
            Information=6, 
            Debug=7, 
        }


        public enum Facility
        {
            Kernel=0, 
            User=1, 
            Mail=2, 
            Daemon=3, 
            Auth=4, 
            Syslog=5, 
            Lpr=6, 
            News=7, 
            UUCP=8, 
            Cron=9, 
            Local0=10, 
            Local1=11, 
            Local2=12, 
            Local3=13, 
            Local4=14, 
            Local5=15, 
            Local6=16, 
            Local7=17, 
        }

        int Port;
        string Server;
        string DeviceName;
        Socket socket;
        ManualResetEvent waitOnSend = new ManualResetEvent(false);

        public SyslogClient(string strServer, int iPort = 514)
        {
            Server = strServer;
            Port = iPort;
            object MyDeviceName;
            if (DeviceExtendedProperties.TryGetValue("DeviceName", out MyDeviceName))
            {
                DeviceName = MyDeviceName.ToString();
            }
        }

        public void SendSyslogMessage(Severity severity, Facility facility, string Message)
        {
            InternSendSyslog(CreateSyslogString(CreatePriorityCode(severity,facility),Message));
        }

        private int CreatePriorityCode(Severity severity, Facility facility)
        {
            return (int)facility * 8 + (int)severity;
        }

        private string CreateSyslogString(int iPrority, string Message)
        {
            return System.String.Format("<{0}>{1} {2} {3}",
                                              iPrority,
                                              DateTime.Now.ToString("dd MMM yyyy HH:mm:ss"),
                                              DeviceName,
                                              Message);
        }

        private void InternSendSyslog(string strMessage)
        {
            waitOnSend.Reset();
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            SocketAsyncEventArgs args = new SocketAsyncEventArgs();
            args.RemoteEndPoint = new DnsEndPoint(Server, Port);
            args.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object sender, SocketAsyncEventArgs e)
                {
                    socket.Close();
                    waitOnSend.Set();
                });
            
            byte[] Message = null;
            Message = Encoding.UTF8.GetBytes(string.Concat(strMessage));

            args.SetBuffer(Message, 0, Message.Length);
            socket.SendToAsync(args);
            waitOnSend.WaitOne();
        }
    }
}