using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Windows.Forms;
using System.ComponentModel;
using System.Data;
using OPCTrendControl;
using System.IO.Compression;
using System.IO;
using System.Net.Mail;

namespace OPCMonitoring
{

    /// <summary>
    /// Controller that handles sending emails
    /// </summary>
    public class MailController
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="MailController"/> class.
        /// </summary>
        public MailController()
        {

        }


        /// <summary>
        /// Gets all emails from Mails\Mails.xml file.
        /// </summary>
        /// <returns>Table with all the emails</returns>
        public static DataTable GetAll()
        {
            DataTable mailsDT = new DataTable();
            mailsDT.Columns.Add("Email");
            mailsDT.Columns.Add("Active", typeof(bool));

            XmlDocument document = new XmlDocument();
            document.Load(Application.StartupPath + "\\Mails\\Mails.xml");

            foreach (XmlNode email in document.SelectNodes("mails/mail"))
            {
                DataRow row = mailsDT.NewRow();
                row.BeginEdit();
                row[0] = email.ChildNodes[0].InnerText;
                row[1] = email.ChildNodes[1].InnerText;
                mailsDT.Rows.Add(row);
            }
            return mailsDT;
        }

        /// <summary>
        /// Overrides the specified mails.
        /// </summary>
        /// <param name="mails">The mails.</param>
        public static void Override(DataTable mails)
        {
            XmlDocument document = new XmlDocument();
            document.Load(Application.StartupPath + "\\Mails\\Mails.xml");

            XmlNode root = document.SelectSingleNode("mails");
            root.RemoveAll();

            foreach (DataRow mail in mails.Rows)
            {
                XmlNode mailNode = document.CreateElement("mail");

                XmlNode emailText = document.CreateElement("email");
                emailText.InnerText = mail[0].ToString();

                XmlNode activeMail = document.CreateElement("active");
                activeMail.InnerText = mail[1].ToString();

                if (mail[1] == null || mail[1] == DBNull.Value)
                    activeMail.InnerText = "False";

                root.AppendChild(mailNode);
                mailNode.AppendChild(emailText);
                mailNode.AppendChild(activeMail);
              
                root.AppendChild(mailNode);
            }

            document.Save(Application.StartupPath + "\\Mails\\Mails.xml");
        }


        /// <summary>
        /// Sends the mail.
        /// </summary>
        /// <param name="rows">The rows in the excel sheet (Each row represents one pen that triggered the alarm</param>
        /// <returns>Number of emails sent</returns>
        public static int SendMail(List<ExcelRow> rows)
        {
            int counter = 0;
            
            StreamReader reader = File.OpenText(Application.StartupPath + "\\ExcelSpreadsheet.txt");
            string text = reader.ReadToEnd();

            string rowsText = string.Empty;
            foreach(ExcelRow row in rows)
            {

                rowsText += "<Row>";
                rowsText += "<Cell><Data ss:Type=\"String\">" + row.Counter + "</Data></Cell>";
                rowsText += "<Cell><Data ss:Type=\"String\">" + row.Machine + "</Data></Cell>";
                rowsText += "<Cell><Data ss:Type=\"String\">" + row.Value + "</Data></Cell>";
                rowsText += "</Row>";
            }

            string attachment = text.Replace("<TOBEREPLACEDBYTHECODE>", rowsText);
            MemoryStream stream = new MemoryStream(ASCIIEncoding.ASCII.GetBytes(attachment));
            stream.Position = 0;

            MemoryStream zippedStream = new MemoryStream();
            GZipStream strem = new GZipStream(zippedStream, CompressionMode.Compress);
            strem.Write(stream.ToArray(), 0, stream.ToArray().Length);
            zippedStream.Position = 0;
            strem.Close();
            zippedStream.Close();

            foreach (DataRow mail in GetAll().Rows)
            {
                if ((bool)mail[1] == false)
                    continue;

                counter++;

                MailMessage msg = new MailMessage();
                msg.To.Add(mail[0].ToString());
                msg.From = new MailAddress("spss009@gmail.com",
                    "One Ghost", System.Text.Encoding.UTF8);
                msg.Subject = "Performance counter values on " + DateTime.Now.ToString();
                msg.SubjectEncoding = System.Text.Encoding.UTF8;
                msg.Body = "Rename the file in zip archive from Values to Values.xls";
                msg.BodyEncoding = System.Text.Encoding.UTF8;
                msg.IsBodyHtml = false;
                msg.Priority = MailPriority.High;

                msg.Attachments.Add(new Attachment(zippedStream, "Values.zip"));

                //Add the Creddentials
                SmtpClient client = new SmtpClient("smtp.gmail.com");
                client.UseDefaultCredentials = false;
                client.DeliveryMethod = SmtpDeliveryMethod.Network;
                client.Credentials = new System.Net.NetworkCredential
                    ("spss009@gmail.com", "spss2009");
                client.Port = 587;//or use 587            
                client.EnableSsl = true;
                object userState = msg;
                try
                {
                    //you can also call client.Send(msg)
                    client.Send(msg);
                }
                catch (System.Net.Mail.SmtpException ex)
                {
                    MessageBox.Show(ex.Message, "Send Mail Error");
                }
            }

            return counter;
        }

        static void client_SendCompleted(object sender, AsyncCompletedEventArgs e)
        {
            
        }
    }

    /// <summary>
    /// Represents the row in excell file sheet
    /// </summary>
    public class ExcelRow
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="ExcelRow"/> class.
        /// </summary>
        public ExcelRow()
        {

        }
        /// <summary>
        /// Gets or sets the name of the pen that caused the alarm.
        /// </summary>
        /// <value>Name of the pen</value>
        public string Counter { get; set; }
        /// <summary>
        /// Gets or sets the machine that caused the alarm.
        /// </summary>
        /// <value>Name of the machine.</value>
        public string Machine { get; set; }
        /// <summary>
        /// Gets or sets the value.
        /// </summary>
        /// <value>The value.</value>
        public string Value { get; set; }
    }
}
