//
// NotifyConfiguration.cs
//
// Author:
//       Carsten Sonne Larsen <cs@innolan.dk>
//
// Copyright (c) 2013-2016 Carsten Sonne Larsen
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

using System;
using System.Collections.Generic;
using Ntp.Analyzer.Localize;
using Ntp.Config;
using Ntp.Process;

namespace Ntp.Analyzer.Config.Root
{
    public sealed class NotifyConfiguration : JobConfiguration
    {
        private NotifyConfiguration(
            string configName,
            int indentLevel,
            bool initialRun,
            bool fixedRun,
            int frequency,
            string mail,
            string subject,
            string sender,
            string server,
            int port,
            string user,
            string pass,
            bool ssl)
            : base(configName, indentLevel, frequency, initialRun, fixedRun)
        {
            this.mail = mail;
            this.subject = subject;
            this.sender = sender;
            this.server = server;
            this.port = port;
            this.user = user;
            this.pass = pass;
            this.ssl = ssl;
        }

        public const string Identifier = ConfigurationKeyword.Notify;

        private const bool DefaultInitialRun = true;
        private const bool DefaultFixedRun = true;
        private const int DefaultFrequency = 1440;
        private const int DefaultSmtpPort = 25;
        private const string DefaultSmtpUser = null;
        private const string DefaultSmtpPass = null;
        private const bool DefaultEnableSsl = false;

        private static readonly String[] Params =
        {
            ConfigurationKeyword.Notify,
            ConfigurationKeyword.Frequency,
            ConfigurationKeyword.InitialRun,
            ConfigurationKeyword.FixedRun,
            ConfigurationKeyword.NotifyRecipient,
            ConfigurationKeyword.NotifySubject,
            ConfigurationKeyword.NotifySender,
            ConfigurationKeyword.NotifySmtpHost,
            ConfigurationKeyword.NotifySmtpPort,
            ConfigurationKeyword.NotifySmtpUser,
            ConfigurationKeyword.NotifySmtpPass,
            ConfigurationKeyword.NotifyEnableSsl
        };

        private readonly string mail;
        private readonly string pass;
        private readonly int port;
        private readonly string sender;
        private readonly string server;
        private readonly bool ssl;
        private readonly string subject;
        private readonly string user;

        public string Mail
        {
            get { return mail; }
        }

        public string Subject
        {
            get { return subject; }
        }

        public string Sender
        {
            get { return sender; }
        }

        public string SmptServer
        {
            get { return server; }
        }

        public int SmtpPort
        {
            get { return port; }
        }

        public string SmtpUser
        {
            get { return user; }
        }

        public string SmtpPass
        {
            get { return pass; }
        }

        public bool EnableSsl
        {
            get { return ssl; }
        }

        protected override IEnumerable<Object> Items
        {
            get
            {
                var items = new List<object> {ConfigName};

                if (ShowDefault || (!ShowDefault && Frequency != DefaultFrequency))
                    items.Add(Frequency);

                if (ShowDefault || (!ShowDefault && InitialRun != DefaultInitialRun))
                    items.Add(InitialRun);

                if (ShowDefault || (!ShowDefault && FixedRun != DefaultFixedRun))
                    items.Add(FixedRun);

                items.AddRange(new List<string>
                {
                    Mail,
                    Subject,
                    Sender,
                    SmptServer
                });

                if (ShowDefault || (!ShowDefault && SmtpPort != DefaultSmtpPort))
                    items.Add(SmtpPort);

                if (ShowDefault || (!ShowDefault && SmtpUser != DefaultSmtpUser))
                    items.Add(SmtpUser);

                if (ShowDefault || (!ShowDefault && SmtpPass != DefaultSmtpPass))
                    items.Add(SmtpPass);

                if (ShowDefault || (!ShowDefault && EnableSsl != DefaultEnableSsl))
                    items.Add(EnableSsl);

                return items.ToArray();
            }
        }

        public override string ToString()
        {
            var list = new List<string> {ConfigurationKeyword.Notify};

            if (ShowDefault || (!ShowDefault && Frequency != DefaultFrequency))
                list.Add(ConfigurationKeyword.Frequency);

            if (ShowDefault || (!ShowDefault && InitialRun != DefaultInitialRun))
                list.Add(ConfigurationKeyword.InitialRun);

            if (ShowDefault || (!ShowDefault && FixedRun != DefaultFixedRun))
                list.Add(ConfigurationKeyword.FixedRun);

            list.AddRange(new List<string>
            {
                ConfigurationKeyword.NotifyRecipient,
                ConfigurationKeyword.NotifySubject,
                ConfigurationKeyword.NotifySender,
                ConfigurationKeyword.NotifySmtpHost
            });

            if (ShowDefault || (!ShowDefault && SmtpPort != DefaultSmtpPort))
                list.Add(ConfigurationKeyword.NotifySmtpPort);

            if (ShowDefault || (!ShowDefault && SmtpUser != DefaultSmtpUser))
                list.Add(ConfigurationKeyword.NotifySmtpUser);

            if (ShowDefault || (!ShowDefault && SmtpPass != DefaultSmtpPass))
                list.Add(ConfigurationKeyword.NotifySmtpPass);

            if (ShowDefault || (!ShowDefault && EnableSsl != DefaultEnableSsl))
                list.Add(ConfigurationKeyword.NotifyEnableSsl);

            return ConfigText(list.ToArray(), Items);
        }

        public static NotifyConfiguration Create(ConfigurationBlock config)
        {
            if (config == null)
                return null;

            Dictionary<String, String> options = GetOptions(Params, config);

            return new NotifyConfiguration(
                GetOptionConfigName(options, Identifier, String.Empty, false),
                config.IndentLevel,
                GetOptionBoolean(options, ConfigurationKeyword.InitialRun, Identifier, false, DefaultInitialRun),
                GetOptionBoolean(options, ConfigurationKeyword.FixedRun, Identifier, false, DefaultFixedRun),
                GetOptionInteger(options, ConfigurationKeyword.Frequency, Identifier, false, DefaultFrequency),
                GetOptionString(options, ConfigurationKeyword.NotifyRecipient, Identifier),
                GetOptionString(options, ConfigurationKeyword.NotifySubject, Identifier),
                GetOptionString(options, ConfigurationKeyword.NotifySender, Identifier),
                GetOptionString(options, ConfigurationKeyword.NotifySmtpHost, Identifier),
                GetOptionInteger(options, ConfigurationKeyword.NotifySmtpPort, Identifier, false, DefaultSmtpPort),
                GetOptionString(options, ConfigurationKeyword.NotifySmtpUser, Identifier, false, DefaultSmtpUser),
                GetOptionString(options, ConfigurationKeyword.NotifySmtpPass, Identifier, false, DefaultSmtpPass),
                GetOptionBoolean(
                    options,
                    ConfigurationKeyword.NotifyEnableSsl,
                    Identifier,
                    false,
                    DefaultEnableSsl)
                );
        }
    }
}