using System;
using System.Globalization;
using System.Security;
using System.Text;
namespace MediaBrowser.Api.Playback.Dash
{
    public class ManifestBuilder
    {
        protected readonly CultureInfo UsCulture = new CultureInfo("en-US");
        public string GetManifestText(StreamState state, string playlistUrl)
        {
            var builder = new StringBuilder();
            var time = TimeSpan.FromTicks(state.RunTimeTicks.Value);
            var duration = "PT" + time.Hours.ToString("00", UsCulture) + "H" + time.Minutes.ToString("00", UsCulture) + "M" + time.Seconds.ToString("00", UsCulture) + ".00S";
            builder.Append("");
            builder.AppendFormat(
                "",
                duration);
            builder.Append("");
            builder.Append("");
            builder.Append("");
            builder.Append(GetVideoAdaptationSet(state, playlistUrl));
            builder.Append(GetAudioAdaptationSet(state, playlistUrl));
            builder.Append("");
            builder.Append("");
            return builder.ToString();
        }
        private string GetVideoAdaptationSet(StreamState state, string playlistUrl)
        {
            var builder = new StringBuilder();
            builder.Append("");
            builder.Append(GetVideoRepresentationOpenElement(state));
            AppendSegmentList(state, builder, "0", playlistUrl);
            builder.Append("");
            builder.Append("");
            return builder.ToString();
        }
        private string GetAudioAdaptationSet(StreamState state, string playlistUrl)
        {
            var builder = new StringBuilder();
            builder.Append("");
            builder.Append(GetAudioRepresentationOpenElement(state));
            builder.Append("");
            AppendSegmentList(state, builder, "1", playlistUrl);
            builder.Append("");
            builder.Append("");
            return builder.ToString();
        }
        private string GetVideoRepresentationOpenElement(StreamState state)
        {
            var codecs = GetVideoCodecDescriptor(state);
            var mime = "video/mp4";
            var xml = "";
            return xml;
        }
        private string GetAudioRepresentationOpenElement(StreamState state)
        {
            var codecs = GetAudioCodecDescriptor(state);
            var mime = "audio/mp4";
            var xml = "";
            return xml;
        }
        private string GetVideoCodecDescriptor(StreamState state)
        {
            // https://developer.apple.com/library/ios/documentation/networkinginternet/conceptual/streamingmediaguide/FrequentlyAskedQuestions/FrequentlyAskedQuestions.html
            // http://www.chipwreck.de/blog/2010/02/25/html-5-video-tag-and-attributes/
            var level = state.TargetVideoLevel ?? 0;
            var profile = state.TargetVideoProfile ?? string.Empty;
            if (profile.IndexOf("high", StringComparison.OrdinalIgnoreCase) != -1)
            {
                if (level >= 4.1)
                {
                    return "avc1.640028";
                }
                if (level >= 4)
                {
                    return "avc1.640028";
                }
                return "avc1.64001f";
            }
            if (profile.IndexOf("main", StringComparison.OrdinalIgnoreCase) != -1)
            {
                if (level >= 4)
                {
                    return "avc1.4d0028";
                }
                if (level >= 3.1)
                {
                    return "avc1.4d001f";
                }
                return "avc1.4d001e";
            }
            if (level >= 3.1)
            {
                return "avc1.42001f";
            }
            return "avc1.42E01E";
        }
        private string GetAudioCodecDescriptor(StreamState state)
        {
            // https://developer.apple.com/library/ios/documentation/networkinginternet/conceptual/streamingmediaguide/FrequentlyAskedQuestions/FrequentlyAskedQuestions.html
            if (string.Equals(state.OutputAudioCodec, "mp3", StringComparison.OrdinalIgnoreCase))
            {
                return "mp4a.40.34";
            }
            // AAC 5ch
            if (state.OutputAudioChannels.HasValue && state.OutputAudioChannels.Value >= 5)
            {
                return "mp4a.40.5";
            }
            // AAC 2ch
            return "mp4a.40.2";
        }
        private void AppendSegmentList(StreamState state, StringBuilder builder, string type, string playlistUrl)
        {
            var extension = ".m4s";
            var seconds = TimeSpan.FromTicks(state.RunTimeTicks ?? 0).TotalSeconds;
            var queryStringIndex = playlistUrl.IndexOf('?');
            var queryString = queryStringIndex == -1 ? string.Empty : playlistUrl.Substring(queryStringIndex);
            var index = 0;
            var duration = 1000000 * state.SegmentLength;
            builder.AppendFormat("", duration.ToString(CultureInfo.InvariantCulture));
            while (seconds > 0)
            {
                var filename = index == 0
                    ? "init"
                    : (index - 1).ToString(UsCulture);
                var segmentUrl = string.Format("dash/{3}/{0}{1}{2}",
                    filename,
                    extension,
                    SecurityElement.Escape(queryString),
                    type);
                if (index == 0)
                {
                    builder.AppendFormat("", segmentUrl);
                }
                else
                {
                    builder.AppendFormat("", segmentUrl);
                }
                seconds -= state.SegmentLength;
                index++;
            }
            builder.Append("");
        }
    }
}