#pragma warning disable CS1591
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.MediaInfo;
namespace MediaBrowser.Controller.Entities
{
    /// 
    /// Class Video.
    /// 
    public class Video : BaseItem,
        IHasAspectRatio,
        ISupportsPlaceHolders,
        IHasMediaSources
    {
        [JsonIgnore]
        public string PrimaryVersionId { get; set; }
        public string[] AdditionalParts { get; set; }
        public string[] LocalAlternateVersions { get; set; }
        public LinkedChild[] LinkedAlternateVersions { get; set; }
        [JsonIgnore]
        public override bool SupportsPlayedStatus => true;
        [JsonIgnore]
        public override bool SupportsPeople => true;
        [JsonIgnore]
        public override bool SupportsInheritedParentImages => true;
        [JsonIgnore]
        public override bool SupportsPositionTicksResume
        {
            get
            {
                var extraType = ExtraType;
                if (extraType.HasValue)
                {
                    if (extraType.Value == Model.Entities.ExtraType.Sample)
                    {
                        return false;
                    }
                    if (extraType.Value == Model.Entities.ExtraType.ThemeVideo)
                    {
                        return false;
                    }
                    if (extraType.Value == Model.Entities.ExtraType.Trailer)
                    {
                        return false;
                    }
                }
                return true;
            }
        }
        public void SetPrimaryVersionId(string id)
        {
            if (string.IsNullOrEmpty(id))
            {
                PrimaryVersionId = null;
            }
            else
            {
                PrimaryVersionId = id;
            }
            PresentationUniqueKey = CreatePresentationUniqueKey();
        }
        public override string CreatePresentationUniqueKey()
        {
            if (!string.IsNullOrEmpty(PrimaryVersionId))
            {
                return PrimaryVersionId;
            }
            return base.CreatePresentationUniqueKey();
        }
        [JsonIgnore]
        public override bool SupportsThemeMedia => true;
        /// 
        /// Gets or sets the timestamp.
        /// 
        /// The timestamp.
        public TransportStreamTimestamp? Timestamp { get; set; }
        /// 
        /// Gets or sets the subtitle paths.
        /// 
        /// The subtitle paths.
        public string[] 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; }
        /// 
        /// 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; }
        public string[] GetPlayableStreamFileNames()
        {
            var videoType = VideoType;
            if (videoType == VideoType.Iso && IsoType == Model.Entities.IsoType.BluRay)
            {
                videoType = VideoType.BluRay;
            }
            else if (videoType == VideoType.Iso && IsoType == Model.Entities.IsoType.Dvd)
            {
                videoType = VideoType.Dvd;
            }
            else
            {
                return Array.Empty();
            }
            throw new NotImplementedException();
        }
        /// 
        /// Gets or sets the aspect ratio.
        /// 
        /// The aspect ratio.
        public string AspectRatio { get; set; }
        public Video()
        {
            AdditionalParts = Array.Empty();
            LocalAlternateVersions = Array.Empty();
            SubtitleFiles = Array.Empty();
            LinkedAlternateVersions = Array.Empty();
        }
        public override bool CanDownload()
        {
            if (VideoType == VideoType.Dvd || VideoType == VideoType.BluRay)
            {
                return false;
            }
            return IsFileProtocol;
        }
        [JsonIgnore]
        public override bool SupportsAddingToPlaylist => true;
        [JsonIgnore]
        public int MediaSourceCount
        {
            get
            {
                if (!string.IsNullOrEmpty(PrimaryVersionId))
                {
                    var item = LibraryManager.GetItemById(PrimaryVersionId);
                    if (item is Video video)
                    {
                        return video.MediaSourceCount;
                    }
                }
                return LinkedAlternateVersions.Length + LocalAlternateVersions.Length + 1;
            }
        }
        [JsonIgnore]
        public bool IsStacked => AdditionalParts.Length > 0;
        [JsonIgnore]
        public override bool HasLocalAlternateVersions => LocalAlternateVersions.Length > 0;
        public IEnumerable GetAdditionalPartIds()
        {
            return AdditionalParts.Select(i => LibraryManager.GetNewItemId(i, typeof(Video)));
        }
        public IEnumerable GetLocalAlternateVersionIds()
        {
            return LocalAlternateVersions.Select(i => LibraryManager.GetNewItemId(i, typeof(Video)));
        }
        public static ILiveTvManager LiveTvManager { get; set; }
        [JsonIgnore]
        public override SourceType SourceType
        {
            get
            {
                if (IsActiveRecording())
                {
                    return SourceType.LiveTV;
                }
                return base.SourceType;
            }
        }
        protected override bool IsActiveRecording()
        {
            return LiveTvManager.GetActiveRecordingInfo(Path) != null;
        }
        public override bool CanDelete()
        {
            if (IsActiveRecording())
            {
                return false;
            }
            return base.CanDelete();
        }
        [JsonIgnore]
        public bool IsCompleteMedia
        {
            get
            {
                if (SourceType == SourceType.Channel)
                {
                    return !Tags.Contains("livestream", StringComparer.OrdinalIgnoreCase);
                }
                return !IsActiveRecording();
            }
        }
        [JsonIgnore]
        protected virtual bool EnableDefaultVideoUserDataKeys => true;
        public override List GetUserDataKeys()
        {
            var list = base.GetUserDataKeys();
            if (EnableDefaultVideoUserDataKeys)
            {
                if (ExtraType.HasValue)
                {
                    var key = this.GetProviderId(MetadataProvider.Tmdb);
                    if (!string.IsNullOrEmpty(key))
                    {
                        list.Insert(0, GetUserDataKey(key));
                    }
                    key = this.GetProviderId(MetadataProvider.Imdb);
                    if (!string.IsNullOrEmpty(key))
                    {
                        list.Insert(0, GetUserDataKey(key));
                    }
                }
                else
                {
                    var key = this.GetProviderId(MetadataProvider.Imdb);
                    if (!string.IsNullOrEmpty(key))
                    {
                        list.Insert(0, key);
                    }
                    key = this.GetProviderId(MetadataProvider.Tmdb);
                    if (!string.IsNullOrEmpty(key))
                    {
                        list.Insert(0, key);
                    }
                }
            }
            return list;
        }
        private string GetUserDataKey(string providerId)
        {
            var key = providerId + "-" + ExtraType.ToString().ToLowerInvariant();
            // Make sure different trailers have their own data.
            if (RunTimeTicks.HasValue)
            {
                key += "-" + RunTimeTicks.Value.ToString(CultureInfo.InvariantCulture);
            }
            return key;
        }
        public IEnumerable