using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.Users;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
namespace MediaBrowser.Controller.Entities.Audio
{
    /// 
    /// Class Audio
    /// 
    public class Audio : BaseItem,
        IHasAlbumArtist,
        IHasArtist,
        IHasMusicGenres,
        IHasLookupInfo,
        IHasTags,
        IHasMediaSources,
        IThemeMedia,
        IArchivable
    {
        public long? Size { get; set; }
        public string Container { get; set; }
        public int? TotalBitrate { get; set; }
        public List Tags { get; set; }
        public ExtraType? ExtraType { get; set; }
        [IgnoreDataMember]
        public bool IsThemeMedia
        {
            get
            {
                return ExtraType.HasValue && ExtraType.Value == Model.Entities.ExtraType.ThemeSong;
            }
        }
        public Audio()
        {
            Artists = new List();
            AlbumArtists = new List();
            Tags = new List();
        }
        [IgnoreDataMember]
        public override bool SupportsAddingToPlaylist
        {
            get { return LocationType == LocationType.FileSystem && RunTimeTicks.HasValue; }
        }
        [IgnoreDataMember]
        protected override bool SupportsOwnedItems
        {
            get
            {
                return false;
            }
        }
        [IgnoreDataMember]
        public override Folder LatestItemsIndexContainer
        {
            get
            {
                return AlbumEntity;
            }
        }
        [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 override bool CanDownload()
        {
            var locationType = LocationType;
            return locationType != LocationType.Remote &&
                   locationType != LocationType.Virtual;
        }
        /// 
        /// Gets or sets the artist.
        /// 
        /// The artist.
        public List Artists { get; set; }
        public List AlbumArtists { get; set; }
        
        [IgnoreDataMember]
        public List AllArtists
        {
            get
            {
                var list = AlbumArtists.ToList();
                list.AddRange(Artists);
                return list;
            }
        }
        /// 
        /// Gets or sets the album.
        /// 
        /// The album.
        public string Album { get; set; }
        [IgnoreDataMember]
        public MusicAlbum AlbumEntity
        {
            get { return FindParent(); }
        }
        /// 
        /// Gets the type of the media.
        /// 
        /// The type of the media.
        [IgnoreDataMember]
        public override string MediaType
        {
            get
            {
                return Model.Entities.MediaType.Audio;
            }
        }
        /// 
        /// Creates the name of the sort.
        /// 
        /// System.String.
        protected override string CreateSortName()
        {
            return (ParentIndexNumber != null ? ParentIndexNumber.Value.ToString("0000 - ") : "")
                    + (IndexNumber != null ? IndexNumber.Value.ToString("0000 - ") : "") + Name;
        }
        /// 
        /// Gets the user data key.
        /// 
        /// System.String.
        protected override string CreateUserDataKey()
        {
            var parent = AlbumEntity;
            if (parent != null)
            {
                var parentKey = parent.GetUserDataKey();
                if (IndexNumber.HasValue)
                {
                    var songKey = (ParentIndexNumber != null ? ParentIndexNumber.Value.ToString("0000 - ") : "")
                                  + (IndexNumber.Value.ToString("0000 - "));
                    return parentKey + songKey;
                }
            }
            return base.CreateUserDataKey();
        }
        protected override bool GetBlockUnratedValue(UserPolicy config)
        {
            return config.BlockUnratedItems.Contains(UnratedItem.Music);
        }
        public SongInfo GetLookupInfo()
        {
            var info = GetItemLookupInfo();
            info.AlbumArtists = AlbumArtists;
            info.Album = Album;
            info.Artists = Artists;
            return info;
        }
        public virtual IEnumerable GetMediaSources(bool enablePathSubstitution)
        {
            var result = new List
            {
                GetVersionInfo(this, enablePathSubstitution)
            };
            return result;
        }
        private static MediaSourceInfo GetVersionInfo(Audio i, bool enablePathSubstituion)
        {
            var locationType = i.LocationType;
            var info = new MediaSourceInfo
            {
                Id = i.Id.ToString("N"),
                Protocol = locationType == LocationType.Remote ? MediaProtocol.Http : MediaProtocol.File,
                MediaStreams = MediaSourceManager.GetMediaStreams(i.Id).ToList(),
                Name = i.Name,
                Path = enablePathSubstituion ? GetMappedPath(i.Path, locationType) : i.Path,
                RunTimeTicks = i.RunTimeTicks,
                Container = i.Container,
                Size = i.Size
            };
            if (string.IsNullOrEmpty(info.Container))
            {
                if (!string.IsNullOrWhiteSpace(i.Path) && locationType != LocationType.Remote && locationType != LocationType.Virtual)
                {
                    info.Container = System.IO.Path.GetExtension(i.Path).TrimStart('.');
                }
            }
            var bitrate = i.TotalBitrate ??
                info.MediaStreams.Where(m => m.Type == MediaStreamType.Audio)
                .Select(m => m.BitRate ?? 0)
                .Sum();
            if (bitrate > 0)
            {
                info.Bitrate = bitrate;
            }
            return info;
        }
    }
}