#nullable enable using System; using System.Threading.Tasks; using Serilog; namespace NadekoBot.Core.Modules.Music { public sealed class TrackResolveProvider : ITrackResolveProvider { private readonly IYoutubeResolver _ytResolver; private readonly ILocalTrackResolver _localResolver; private readonly ISoundcloudResolver _soundcloudResolver; private readonly IRadioResolver _radioResolver; public TrackResolveProvider(IYoutubeResolver ytResolver, ILocalTrackResolver localResolver, ISoundcloudResolver soundcloudResolver, IRadioResolver radioResolver) { _ytResolver = ytResolver; _localResolver = localResolver; _soundcloudResolver = soundcloudResolver; _radioResolver = radioResolver; } public Task QuerySongAsync(string query, MusicPlatform? forcePlatform) { switch (forcePlatform) { case MusicPlatform.Radio: return _radioResolver.ResolveByQueryAsync(query); case MusicPlatform.Youtube: return _ytResolver.ResolveByQueryAsync(query); case MusicPlatform.Local: return _localResolver.ResolveByQueryAsync(query); case MusicPlatform.SoundCloud: return _soundcloudResolver.ResolveByQueryAsync(query); case null: var match = _ytResolver.YtVideoIdRegex.Match(query); if (match.Success) return _ytResolver.ResolveByIdAsync(match.Groups["id"].Value); else if (_soundcloudResolver.IsSoundCloudLink(query)) return _soundcloudResolver.ResolveByQueryAsync(query); else if (Uri.TryCreate(query, UriKind.Absolute, out var uri) && uri.IsFile) return _localResolver.ResolveByQueryAsync(uri.AbsolutePath); else if (IsRadioLink(query)) return _radioResolver.ResolveByQueryAsync(query); else return _ytResolver.ResolveByQueryAsync(query, false); default: Log.Error("Unsupported platform: {MusicPlatform}", forcePlatform); return Task.FromResult(null); } } public static bool IsRadioLink(string query) => (query.StartsWith("http", StringComparison.InvariantCulture) || query.StartsWith("ww", StringComparison.InvariantCulture)) && (query.Contains(".pls") || query.Contains(".m3u") || query.Contains(".asx") || query.Contains(".xspf")); } }