using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.MediaInfo;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Runtime.Serialization;
using System.Threading;
using System.Threading.Tasks;
using CommonIO;
using MediaBrowser.Controller.Channels;
namespace MediaBrowser.Controller.Entities
{
    /// 
    /// Class Video
    /// 
    public class Video : BaseItem,
        IHasAspectRatio,
        ISupportsPlaceHolders,
        IHasMediaSources,
        IHasShortOverview,
        IThemeMedia,
        IArchivable
    {
        [IgnoreDataMember]
        public string PrimaryVersionId { get; set; }
        public List AdditionalParts { get; set; }
        public List LocalAlternateVersions { get; set; }
        public List LinkedAlternateVersions { get; set; }
        public List ChannelMediaSources { get; set; }
        [IgnoreDataMember]
        public bool IsThemeMedia
        {
            get
            {
                return ExtraType.HasValue && ExtraType.Value == Model.Entities.ExtraType.ThemeVideo;
            }
        }
        [IgnoreDataMember]
        public override string PresentationUniqueKey
        {
            get
            {
                if (!string.IsNullOrWhiteSpace(PrimaryVersionId))
                {
                    return PrimaryVersionId;
                }
                return base.PresentationUniqueKey;
            }
        }
        public long? Size { get; set; }
        public string Container { get; set; }
        public int? TotalBitrate { get; set; }
        public string ShortOverview { get; set; }
        public ExtraType? ExtraType { get; set; }
        /// 
        /// Gets or sets the timestamp.
        /// 
        /// The timestamp.
        public TransportStreamTimestamp? Timestamp { get; set; }
        /// 
        /// Gets or sets the subtitle paths.
        /// 
        /// The subtitle paths.
        public List SubtitleFiles { get; set; }
        /// 
        /// Gets or sets a value indicating whether this instance has subtitles.
        /// 
        /// true if this instance has subtitles; otherwise, false.
        public bool HasSubtitles { get; set; }
        public bool IsPlaceHolder { get; set; }
        public bool IsShortcut { get; set; }
        public string ShortcutPath { get; set; }
        /// 
        /// Gets or sets the video bit rate.
        /// 
        /// The video bit rate.
        public int? VideoBitRate { get; set; }
        /// 
        /// Gets or sets the default index of the video stream.
        /// 
        /// The default index of the video stream.
        public int? DefaultVideoStreamIndex { get; set; }
        /// 
        /// Gets or sets the type of the video.
        /// 
        /// The type of the video.
        public VideoType VideoType { get; set; }
        /// 
        /// Gets or sets the type of the iso.
        /// 
        /// The type of the iso.
        public IsoType? IsoType { get; set; }
        /// 
        /// Gets or sets the video3 D format.
        /// 
        /// The video3 D format.
        public Video3DFormat? Video3DFormat { get; set; }
        /// 
        /// If the video is a folder-rip, this will hold the file list for the largest playlist
        /// 
        public List PlayableStreamFileNames { get; set; }
        /// 
        /// Gets the playable stream files.
        /// 
        /// List{System.String}.
        public List GetPlayableStreamFiles()
        {
            return GetPlayableStreamFiles(Path);
        }
        /// 
        /// Gets or sets the aspect ratio.
        /// 
        /// The aspect ratio.
        public string AspectRatio { get; set; }
        public Video()
        {
            PlayableStreamFileNames = new List();
            AdditionalParts = new List();
            LocalAlternateVersions = new List();
            Tags = new List();
            SubtitleFiles = new List();
            LinkedAlternateVersions = new List();
        }
        public override bool CanDownload()
        {
            if (VideoType == VideoType.HdDvd || VideoType == VideoType.Dvd ||
                VideoType == VideoType.BluRay)
            {
                return false;
            }
            var locationType = LocationType;
            return locationType != LocationType.Remote &&
                   locationType != LocationType.Virtual;
        }
        [IgnoreDataMember]
        public override bool SupportsAddingToPlaylist
        {
            get { return LocationType == LocationType.FileSystem && RunTimeTicks.HasValue; }
        }
        [IgnoreDataMember]
        public int MediaSourceCount
        {
            get
            {
                if (!string.IsNullOrWhiteSpace(PrimaryVersionId))
                {
                    var item = LibraryManager.GetItemById(PrimaryVersionId) as Video;
                    if (item != null)
                    {
                        return item.MediaSourceCount;
                    }
                }
                return LinkedAlternateVersions.Count + LocalAlternateVersions.Count + 1;
            }
        }
        [IgnoreDataMember]
        public bool IsStacked
        {
            get { return AdditionalParts.Count > 0; }
        }
        [IgnoreDataMember]
        public bool HasLocalAlternateVersions
        {
            get { return LocalAlternateVersions.Count > 0; }
        }
        [IgnoreDataMember]
        public bool IsArchive
        {
            get
            {
                if (string.IsNullOrWhiteSpace(Path))
                {
                    return false;
                }
                var ext = System.IO.Path.GetExtension(Path) ?? string.Empty;
                return new[] { ".zip", ".rar", ".7z" }.Contains(ext, StringComparer.OrdinalIgnoreCase);
            }
        }
        public IEnumerable GetAdditionalPartIds()
        {
            return AdditionalParts.Select(i => LibraryManager.GetNewItemId(i, typeof(Video)));
        }
        public IEnumerable GetLocalAlternateVersionIds()
        {
            return LocalAlternateVersions.Select(i => LibraryManager.GetNewItemId(i, typeof(Video)));
        }
        [IgnoreDataMember]
        protected virtual bool EnableDefaultVideoUserDataKeys
        {
            get
            {
                return true;
            }
        }
        public override List GetUserDataKeys()
        {
            var list = base.GetUserDataKeys();
            if (EnableDefaultVideoUserDataKeys)
            {
                if (ExtraType.HasValue)
                {
                    var key = this.GetProviderId(MetadataProviders.Tmdb);
                    if (!string.IsNullOrWhiteSpace(key))
                    {
                        list.Insert(0, GetUserDataKey(key));
                    }
                    key = this.GetProviderId(MetadataProviders.Imdb);
                    if (!string.IsNullOrWhiteSpace(key))
                    {
                        list.Insert(0, GetUserDataKey(key));
                    }
                }
                else
                {
                    var key = this.GetProviderId(MetadataProviders.Imdb);
                    if (!string.IsNullOrWhiteSpace(key))
                    {
                        list.Insert(0, key);
                    }
                    key = this.GetProviderId(MetadataProviders.Tmdb);
                    if (!string.IsNullOrWhiteSpace(key))
                    {
                        list.Insert(0, key);
                    }
                }
            }
            return list;
        }
        private string GetUserDataKey(string providerId)
        {
            var key = providerId + "-" + ExtraType.ToString().ToLower();
            // Make sure different trailers have their own data.
            if (RunTimeTicks.HasValue)
            {
                key += "-" + RunTimeTicks.Value.ToString(CultureInfo.InvariantCulture);
            }
            return key;
        }
        public IEnumerable