// 
// Copyright (c) 2013-2016 Carsten Sonne Larsen <cs@innolan.dk>
// 
// 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 System.Text;
using Ntp.Analyzer.Config.Node.Page;
using Ntp.Analyzer.Import;

namespace Ntp.Analyzer.Render.Host
{
    public sealed class BootstrapHostTableRender : HtmlObjectRender
    {
        public BootstrapHostTableRender(
            HostPageConfiguration page,
            string ip,
            DateTime now,
            DateTime next)
            : base(page.WebPath)
        {
            this.page = page;
            this.ip = ip;
            this.now = now;
            this.next = next;

            columns = new List<BootstrapTableColumn>
            {
                new BootstrapTableColumn(),
                new BootstrapTableColumn("Name"),
                new BootstrapTableColumn("st", "aright"),
                new BootstrapTableColumn("when", "aright"),
                new BootstrapTableColumn("poll", "aright2"),
                page.ServerType == ServerType.Ntpctl
                    ? new BootstrapTableColumn("trust", "aright2")
                    : new BootstrapTableColumn("reach", "aright2"),
                new BootstrapTableColumn("delay", "aright"),
                new BootstrapTableColumn("offset", "aright"),
                new BootstrapTableColumn("jitter", "aright"),
                new BootstrapTableColumn("iso&nbsp;"),
                new BootstrapTableColumn("location")
            }.ToArray();
        }

        private readonly BootstrapTableColumn[] columns;
        private readonly string ip;
        private readonly DateTime next;
        private readonly DateTime now;
        private readonly HostPageConfiguration page;

        public override string Render()
        {
            return string.Empty;
        }

        public override string RenderFooter()
        {
            var builder = new StringBuilder();

            builder.Append(MakeSpacer());

            builder.Append("<tr>");

            foreach (var column in columns)
            {
                builder.Append(column.FooterString);
            }

            builder.AppendLine("</tr>");
            builder.AppendLine("</table>");
            builder.AppendLine("</div>");

            if (page.PoolMember)
            {
                builder.Append(@"<p class=""pool""><a class=""btn btn-lg btn-primary"" ");
                builder.Append($@"href=""{GetPoolMemberLink()}"">View info on pool.ntp.org &raquo;</a></p>");
                builder.AppendLine();
            }

            builder.AppendLine("</div>");
            builder.AppendLine("</div>");

            return builder.ToString();
        }

        public override string RenderHead()
        {
            var builder = new StringBuilder();

            builder.AppendLine(@"<div class=""container theme-showcase"">");
            builder.AppendLine(@"<div class=""jumbotron"">");
            builder.Append("<h1>");
            builder.Append(page.Title);
            builder.AppendLine("</h1>");

            builder.Append("<p>");
            builder.Append(now.ToLongDateString() + " ");
            if (page.ShowUtc == DateTimeKind.Utc)
            {
                builder.Append(TimeZoneInfo.Utc.StandardName);
            }
            else
            {
                builder.Append(TimeZoneInfo.Local.IsDaylightSavingTime(now)
                    ? TimeZoneInfo.Local.DaylightName
                    : TimeZoneInfo.Local.StandardName);
            }
            builder.Append(" " + now.ToShortTimeString() + ". ");
            builder.Append("Next refresh scheduled at ");
            builder.Append(next.ToShortTimeString());
            builder.AppendLine(".</p>");

            builder.AppendLine(@"<div class=""table-responsive"">");
            builder.Append("<table><tr>");

            foreach (var column in columns)
            {
                builder.Append(column);
            }

            builder.AppendLine("</tr>");

            builder.Append(MakeSpacer());

            return builder.ToString();
        }

        private string GetPoolMemberLink()
        {
            return "http://www.pool.ntp.org/scores/" + ip;
        }

        private string MakeSpacer()
        {
            var builder = new StringBuilder();

            builder.Append("<tr>");

            foreach (var column in columns)
            {
                builder.Append(column.SpacerString);
            }

            builder.AppendLine("</tr>");

            return builder.ToString();
        }

        private sealed class BootstrapTableColumn
        {
            public BootstrapTableColumn(string name, string cssClass)
            {
                this.name = name;
                this.cssClass = cssClass;
            }

            public BootstrapTableColumn(string name)
            {
                this.name = name;
                cssClass = null;
            }

            public BootstrapTableColumn()
            {
                name = "&nbsp;";
                cssClass = null;
            }

            private readonly string cssClass;
            private readonly string name;

            public string SpacerString =>
                $@"<td class=""spc{(cssClass != null ? " " + cssClass : string.Empty)}"">&nbsp;</td>";

            public string FooterString =>
                $@"<td class=""but{(cssClass != null ? " " + cssClass : string.Empty)}"">&nbsp;</td>";

            public override string ToString()
            {
                return cssClass != null
                    ? $@"<th class=""{cssClass}"">{name}</th>"
                    : $@"<th>{name}</th>";
            }
        }
    }
}