private Dictionary<string, object> GetMediaVersionFIX(int? id, int p = 0, int q = 0)
        {
            Dictionary<string, object> collection = new Dictionary<string, object>();
            ErrorCodes errorCode = ErrorCodes.UnknownError;
            string errorMessage = MyUtility.getErrorMessage(ErrorCodes.UnknownError);
            collection = MyUtility.setError(errorCode, errorMessage);

            if (!(Request.IsLocal || GlobalConfig.isUAT))
                if (!Request.IsAjaxRequest())
                {
                    errorCode = ErrorCodes.IsInvalidRequest;
                    collection = MyUtility.setError(errorCode, "Request is not valid.");
                    return collection;
                }

            try
            {
                var context = new IPTV2Entities();
                string CountryCode = MyUtility.GetCountryCodeViaIpAddressWithoutProxy();
                User user = null;
                if (GlobalConfig.IsPreventionOfMultipleLoginUsingSessionDatabaseEnabled)
                {
                    if (User.Identity.IsAuthenticated)
                    {
                        HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
                        var UserId = new Guid(User.Identity.Name);
                        user = context.Users.FirstOrDefault(u => u.UserId == UserId);
                        if (user != null)
                        {
                            CountryCode = user.CountryCode;
                            if (!MyUtility.IsWhiteListed(user.EMail))
                            {
                                if (!String.IsNullOrEmpty(user.SessionId))
                                {
                                    if (String.Compare(user.SessionId, authCookie.Value, true) != 0)
                                    {
                                        collection = MyUtility.setError(ErrorCodes.MultipleLoginDetected, "Not allowed to use account.");
                                        collection.Add("uid", User.Identity.Name);
                                        FormsAuthentication.SignOut();
                                        return collection;
                                    }
                                }
                            }
                        }
                    }
                }

                Episode episode = context.Episodes.FirstOrDefault(e => e.EpisodeId == id);
                DateTime registDt = DateTime.Now;
                if (episode != null)
                {
                    if (episode.OnlineStatusId == GlobalConfig.Visible && episode.OnlineStartDate < registDt && episode.OnlineEndDate > registDt)
                    {
                        Offering offering = context.Offerings.Find(GlobalConfig.offeringId);
                        AkamaiFlowPlayerPluginClipDetails clipDetails = null;
                        var ShowListBasedOnCountryCode = ContextHelper.GetAllShowsBasedOnCountryCode(context, CountryCode, true, offering);
                        //var episodeCategory = episode.EpisodeCategories.FirstOrDefault(e => ShowListBasedOnCountryCode.Contains(e.CategoryId));
                        var categoryIds = episode.EpisodeCategories.Where(e => ShowListBasedOnCountryCode.Contains(e.CategoryId));
                        var HasActiveSubscriptionBasedOnCategoryId = new CheckSubscriptionReturnObject() { HasSubscription = false, Within5DaysOrLess = false };
                        if (categoryIds != null)
                            HasActiveSubscriptionBasedOnCategoryId = ContextHelper.HasActiveSubscriptionBasedOnCategoryId(user, categoryIds.Select(c => c.CategoryId), registDt);
                        //HasActiveSubscriptionBasedOnCategoryId = ContextHelper.HasActiveSubscriptionBasedOnCategoryId(user, episodeCategory.CategoryId, registDt);                       

                        if (HasActiveSubscriptionBasedOnCategoryId.HasSubscription) // Get premium asset
                        {
                            collection = ProcessPremiumAssetFIX(episode, p, q);
                        }
                        else //get preview asset
                        {
                            var previewAsset = episode.PreviewAssets.LastOrDefault();
                            if (previewAsset != null)
                            {
                                collection = ProcessPreviewAssetFIX(episode, p, q);
                            }
                            else // no preview asset, use 60 seconds
                            {
                                if (!(episode.IsLiveChannelActive == true))
                                {
                                    if (Akamai.IsIos(Request))
                                    {
                                        errorCode = ErrorCodes.IPodPreviewNotAvailable;
                                        collection = MyUtility.setError(errorCode, "Media preview not available.");
                                    }
                                    else
                                        collection = ProcessPremiumAssetFIX(episode, p, q);
                                }
                                else
                                {
                                    if (User.Identity.IsAuthenticated)
                                    {
                                        if (!HasActiveSubscriptionBasedOnCategoryId.HasSubscription)
                                        {
                                            errorCode = ErrorCodes.UserIsNotEntitled;
                                            collection = MyUtility.setError(errorCode, "Live event can't be played.");
                                        }
                                    }
                                    else
                                    {
                                        errorCode = ErrorCodes.NotAuthenticated;
                                        collection = MyUtility.setError(errorCode, "You are not logged in.");
                                    }
                                }
                            }
                        }
                        if (clipDetails != null)
                        {
                            if (!String.IsNullOrEmpty(clipDetails.Url))
                            {
                                errorCode = ErrorCodes.Success;
                                collection = MyUtility.setError(errorCode, clipDetails.Url);
                                collection.Add("data", clipDetails);
                            }
                            else
                            {
                                errorCode = ErrorCodes.VideoNotFound;
                                collection = MyUtility.setError(errorCode, "Media not found.");
                                return collection;
                            }
                        }
                    }
                    else
                    {
                        errorCode = ErrorCodes.VideoNotFound;
                        collection = MyUtility.setError(errorCode, "Media not found.");
                    }
                }
                else
                {
                    errorCode = ErrorCodes.EpisodeNotFound;
                    collection = MyUtility.setError(errorCode, "MediaId not found.");
                }
            }
            catch (Exception e) { MyUtility.LogException(e); }
            return collection;
        }
        public ActionResult GetMediaV2(int? id, int p = 0, int q = 0)
        // id = episodeid, p = 1 for progressive-low, 2 for progressive-high, 0 for adaptive
        // c = if 1 it is a channel/live event, else 0, which is normal episode
        {
            Dictionary<string, object> collection = new Dictionary<string, object>();
            ErrorCodes errorCode = ErrorCodes.UnknownError;
            string errorMessage = MyUtility.getErrorMessage(ErrorCodes.UnknownError);
            collection = MyUtility.setError(errorCode, errorMessage);

            if (!Request.IsLocal)
                if (!Request.IsAjaxRequest())
                {
                    errorCode = ErrorCodes.IsInvalidRequest;
                    collection = MyUtility.setError(errorCode, "Request is not valid.");
                    return Content(MyUtility.buildJson(collection), "application/json");
                }

            try
            {
                var context = new IPTV2Entities();
                string CountryCode = MyUtility.GetCountryCodeViaIpAddressWithoutProxy();
                User user = null;
                if (GlobalConfig.IsPreventionOfMultipleLoginUsingSessionDatabaseEnabled)
                {
                    if (User.Identity.IsAuthenticated)
                    {
                        HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
                        var UserId = new Guid(User.Identity.Name);
                        user = context.Users.FirstOrDefault(u => u.UserId == UserId);
                        if (user != null)
                        {
                            CountryCode = user.CountryCode;
                            if (!String.IsNullOrEmpty(user.SessionId))
                            {
                                if (String.Compare(user.SessionId, authCookie.Value, true) != 0)
                                {
                                    collection = MyUtility.setError(ErrorCodes.MultipleLoginDetected, "Not allowed to use account.");
                                    collection.Add("uid", User.Identity.Name);
                                    FormsAuthentication.SignOut();
                                    return Content(MyUtility.buildJson(collection), "application/json");
                                }
                            }
                        }
                    }
                }

                Episode episode = context.Episodes.FirstOrDefault(e => e.EpisodeId == id);
                DateTime registDt = DateTime.Now;
                if (episode != null)
                {
                    if (episode.OnlineStatusId == GlobalConfig.Visible && episode.OnlineStartDate < registDt && episode.OnlineEndDate > registDt)
                    {
                        Offering offering = context.Offerings.Find(GlobalConfig.offeringId);
                        AkamaiFlowPlayerPluginClipDetails clipDetails = null;
                        var ShowListBasedOnCountryCode = ContextHelper.GetAllShowsBasedOnCountryCode(context, CountryCode, true, offering);
                        var episodeCategory = episode.EpisodeCategories.FirstOrDefault(e => ShowListBasedOnCountryCode.Contains(e.CategoryId));
                        var HasActiveSubscriptionBasedOnCategoryId = new CheckSubscriptionReturnObject() { HasSubscription = false, Within5DaysOrLess = false };

                        if (HasActiveSubscriptionBasedOnCategoryId.HasSubscription) // Get premium asset
                        {
                            collection = ProcessPremiumAsset(episode, p, q);
                        }
                        else //get preview asset
                        {
                            var previewAsset = episode.PreviewAssets.LastOrDefault();
                            if (previewAsset != null)
                            {
                                Asset asset = previewAsset.Asset;
                                if (asset != null)
                                {
                                    int assetId = asset == null ? 0 : asset.AssetId;
                                    if (episode.IsLiveChannelActive == true) //isLiveEvent
                                    {
                                        if (!ContextHelper.DoesEpisodeHaveIosCdnReferenceBasedOAsset(previewAsset))
                                        {
                                            if (Request.Browser.IsMobileDevice)
                                            {
                                                errorCode = ErrorCodes.IsNotAvailableOnMobileDevices;
                                                collection = MyUtility.setError(errorCode, "Live event not available on mobile.");
                                                return Content(MyUtility.buildJson(collection), "application/json");
                                            }
                                        }
                                        clipDetails = Helpers.Akamai.GetAkamaiLiveEventClipDetails(episode.EpisodeId, assetId, Request, User, true);
                                    }
                                    else
                                    {
                                        if (p > 0)
                                        {
                                            var progressive = p == 1 ? Progressive.Low : Progressive.High;
                                            if (GlobalConfig.UseProgressiveViaAdaptiveTechnology)
                                                clipDetails = Helpers.Akamai.GetAkamaiProgressiveViaAdaptiveClipDetails(episode.EpisodeId, assetId, Request, User, progressive);
                                            else
                                            {
                                                if (GlobalConfig.CheckForEpisodesToMakeUseOfProgessiveViaAdaptiveTechnology)
                                                {
                                                    if (!String.IsNullOrEmpty(GlobalConfig.EpisodeIdsToMakeUseOfProgressiveViaAdaptiveTechnology))
                                                    {
                                                        var listOfEpisodeIds = MyUtility.StringToIntList(GlobalConfig.EpisodeIdsToMakeUseOfProgressiveViaAdaptiveTechnology);
                                                        if (listOfEpisodeIds.Contains(episode.EpisodeId))
                                                            clipDetails = Helpers.Akamai.GetAkamaiProgressiveViaAdaptiveClipDetails(episode.EpisodeId, assetId, Request, User, progressive);
                                                        else
                                                            clipDetails = Helpers.Akamai.GetAkamaiProgressiveClipDetails(episode.EpisodeId, assetId, Request, User, progressive);
                                                    }
                                                    else
                                                        clipDetails = Helpers.Akamai.GetAkamaiProgressiveClipDetails(episode.EpisodeId, assetId, Request, User, progressive);
                                                }
                                                else
                                                    clipDetails = Helpers.Akamai.GetAkamaiProgressiveClipDetails(episode.EpisodeId, assetId, Request, User, progressive);
                                            }
                                        }
                                        else
                                            clipDetails = Helpers.Akamai.GetAkamaiClipDetails(episode.EpisodeId, assetId, Request, User, null);
                                    }
                                }
                            }
                            else // no preview asset, use 60 seconds
                            {

                                collection = ProcessPremiumAsset(episode, p, q);
                            }
                        }
                        if (!String.IsNullOrEmpty(clipDetails.Url))
                        {
                            errorCode = ErrorCodes.Success;
                            collection = MyUtility.setError(errorCode, clipDetails.Url);
                            collection.Add("data", clipDetails);
                        }
                        else
                        {
                            errorCode = ErrorCodes.VideoNotFound;
                            collection = MyUtility.setError(errorCode, "Media not found.");
                            return Content(MyUtility.buildJson(collection), "application/json");
                        }
                    }
                    else
                    {
                        errorCode = ErrorCodes.VideoNotFound;
                        collection = MyUtility.setError(errorCode, "Media not found.");
                    }
                }
                else
                {
                    errorCode = ErrorCodes.EpisodeNotFound;
                    collection = MyUtility.setError(errorCode, "MediaId not found.");
                }
            }
            catch (Exception e) { MyUtility.LogException(e); }
            return Content(MyUtility.buildJson(collection), "application/json");
        }
        private Dictionary<string, object> TEST_GetMediaVersion_M3U8(int? id, int p = 0, int q = 0)
        {
            Dictionary<string, object> collection = new Dictionary<string, object>();
            ErrorCodes errorCode = ErrorCodes.UnknownError;
            string errorMessage = MyUtility.getErrorMessage(ErrorCodes.UnknownError);
            collection = MyUtility.setError(errorCode, errorMessage);

            if (!Request.IsLocal)
                if (!GlobalConfig.isUAT)
                    if (!Request.IsAjaxRequest())
                    {
                        errorCode = ErrorCodes.IsInvalidRequest;
                        collection = MyUtility.setError(errorCode, "Request is not valid.");
                        return collection;
                    }

            try
            {
                var context = new IPTV2Entities();

                User user = null;
                if (GlobalConfig.IsPreventionOfMultipleLoginUsingSessionDatabaseEnabled)
                {
                    if (User.Identity.IsAuthenticated)
                    {
                        HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
                        var UserId = new Guid(User.Identity.Name);
                        user = context.Users.FirstOrDefault(u => u.UserId == UserId);
                        if (user != null)
                        {
                            if (!MyUtility.IsWhiteListed(user.EMail))
                            {
                                if (!String.IsNullOrEmpty(user.SessionId))
                                {
                                    if (String.Compare(user.SessionId, authCookie.Value, true) != 0)
                                    {
                                        collection = MyUtility.setError(ErrorCodes.MultipleLoginDetected, "Not allowed to use account.");
                                        collection.Add("uid", User.Identity.Name);
                                        FormsAuthentication.SignOut();
                                        return collection;
                                    }
                                }
                            }
                        }
                    }
                }

                Episode episode = context.Episodes.FirstOrDefault(e => e.EpisodeId == id);
                DateTime registDt = DateTime.Now;
                if (episode != null)
                {
                    if (episode.OnlineStatusId == GlobalConfig.Visible && episode.OnlineStartDate < registDt && episode.OnlineEndDate > registDt)
                    {
                        var CacheDuration = new TimeSpan(0, GlobalConfig.GetParentShowsForEpisodeCacheDuration, 0);
                        var parentCategories = episode.GetParentShows(CacheDuration);

                        Offering offering = context.Offerings.Find(GlobalConfig.offeringId);
                        AkamaiFlowPlayerPluginClipDetails clipDetails = null;
                        //var episodeCategory = episode.EpisodeCategories.FirstOrDefault(e => ShowListBasedOnCountryCode.Contains(e.CategoryId));
                        //var categoryIds = episode.EpisodeCategories.Where(e => ShowListBasedOnCountryCode.Contains(e.CategoryId));
                        var HasActiveSubscriptionBasedOnCategoryId = new CheckSubscriptionReturnObject() { HasSubscription = false, Within5DaysOrLess = false };
                        if (parentCategories != null)
                            HasActiveSubscriptionBasedOnCategoryId = ContextHelper.HasActiveSubscriptionBasedOnCategoryId(user, parentCategories, registDt, null);
                        //HasActiveSubscriptionBasedOnCategoryId = ContextHelper.HasActiveSubscriptionBasedOnCategoryId(user, episodeCategory.CategoryId, registDt);                       

                        if (HasActiveSubscriptionBasedOnCategoryId.HasSubscription) // Get premium asset
                        {
                            collection = ProcessPremiumAsset_M3U8(episode, p, q);
                        }
                        else //get preview asset
                        {
                            var previewAsset = episode.PreviewAssets.LastOrDefault();
                            if (previewAsset != null)
                            {
                                collection = ProcessPreviewAsset_M3U8(episode, p, q);
                            }
                            else // no preview asset, use 60 seconds
                            {
                                if (!(episode.IsLiveChannelActive == true))
                                {
                                    if (Request.Browser.IsMobileDevice)
                                    {
                                        errorCode = ErrorCodes.IPodPreviewNotAvailable;
                                        collection = MyUtility.setError(errorCode, "This stream is not available on this device");
                                    }
                                    else
                                        collection = ProcessPremiumAsset_M3U8(episode, p, q);
                                }
                                else
                                {
                                    if (User.Identity.IsAuthenticated)
                                    {
                                        if (!HasActiveSubscriptionBasedOnCategoryId.HasSubscription)
                                        {
                                            errorCode = ErrorCodes.UserIsNotEntitled;
                                            collection = MyUtility.setError(errorCode, "You must be subscribed to watch this stream");
                                        }
                                    }
                                    else
                                    {
                                        if (!HasActiveSubscriptionBasedOnCategoryId.HasSubscription)
                                        {
                                            errorCode = ErrorCodes.NotAuthenticated;
                                            collection = MyUtility.setError(errorCode, "You must be logged in to watch this stream");
                                        }
                                    }
                                }
                            }
                        }
                        if (clipDetails != null)
                        {
                            if (!String.IsNullOrEmpty(clipDetails.Url))
                            {
                                errorCode = ErrorCodes.Success;
                                collection = MyUtility.setError(errorCode, clipDetails.Url);
                                collection.Add("data", clipDetails);
                            }
                            else
                            {
                                errorCode = ErrorCodes.VideoNotFound;
                                collection = MyUtility.setError(errorCode, "This video does not exist on this site");
                                return collection;
                            }
                        }
                    }
                    else
                    {
                        errorCode = ErrorCodes.VideoNotFound;
                        collection = MyUtility.setError(errorCode, "This video does not exist on this site");
                    }
                }
                else
                {
                    errorCode = ErrorCodes.EpisodeNotFound;
                    collection = MyUtility.setError(errorCode, "This video does not exist on this site");
                }
            }
            catch (Exception e) { MyUtility.LogException(e); }
            return collection;
        }
        public JsonResult Asap20HLS()
        {
            var ReturnCode = new ServiceReturnType()
            {
                StatusCode = (int)ErrorCodes.UnknownError,
                StatusMessage = String.Empty
            };

            try
            {
                if (!Request.IsLocal)
                {
                    Regex rx = new Regex(GlobalConfig.Asap20InLondonAllowedDomains);
                    if (!rx.IsMatch(Request.Url.Host))
                    {
                        ReturnCode.StatusMessage = String.Format("Unauthorized: {0}", Request.Url.Host);
                        return this.Json(ReturnCode, JsonRequestBehavior.AllowGet);
                    }
                }
            }
            catch (Exception) { }
            //if (!Request.IsLocal)
            //    if (!GlobalConfig.isUAT)
            //        if (!Request.IsAjaxRequest())
            //        {
            //            ReturnCode.StatusCode = (int)ErrorCodes.IsInvalidRequest;
            //            ReturnCode.StatusMessage = "Request is not valid.";
            //            return this.Json(ReturnCode, JsonRequestBehavior.AllowGet);
            //        }

            int id = GlobalConfig.Asap20InLondonEpisodeId;
            DateTime registDt = DateTime.Now;
            try
            {
                string CountryCode = MyUtility.GetCountryCodeViaIpAddressWithoutProxy();
                using (var context = new IPTV2Entities())
                {
                    Episode episode = context.Episodes.FirstOrDefault(e => e.EpisodeId == id);
                    if (episode != null)
                    {
                        if (episode.OnlineStatusId == GlobalConfig.Visible && episode.OnlineStartDate < registDt && episode.OnlineEndDate > registDt)
                        {
                            Offering offering = context.Offerings.Find(GlobalConfig.offeringId);
                            AkamaiFlowPlayerPluginClipDetails clipDetails = null;
                            var HasActiveSubscriptionBasedOnCategoryId = new CheckSubscriptionReturnObject() { HasSubscription = true, Within5DaysOrLess = false };
                            if (HasActiveSubscriptionBasedOnCategoryId.HasSubscription)
                            {
                                var premiumAsset = episode.PremiumAssets.LastOrDefault();
                                if (premiumAsset != null)
                                {
                                    Asset asset = premiumAsset.Asset;
                                    if (asset != null)
                                    {
                                        int assetId = asset == null ? 0 : asset.AssetId;
                                        if (episode.IsLiveChannelActive == true) //isLiveEvent
                                        {
                                            if (!ContextHelper.DoesEpisodeHaveIosCdnReferenceBasedOAsset(premiumAsset))
                                            {
                                                if (Request.Browser.IsMobileDevice)
                                                {
                                                    ReturnCode.StatusCode = (int)ErrorCodes.IsNotAvailableOnMobileDevices;
                                                    ReturnCode.StatusMessage = "This stream is not available on this device";
                                                    return this.Json(ReturnCode, JsonRequestBehavior.AllowGet);
                                                }
                                            }

                                            //clipDetails = Helpers.Akamai.GetAkamaiLiveEventClipDetails(episode.EpisodeId, assetId, Request, User, true, removeIpFromToken: true);
                                            clipDetails = Helpers.Akamai.GetAkamaiLiveEventClipDetails_M3U8(episode.EpisodeId, assetId, Request, User, true, CountryCodeOverride: String.Empty, RemoveIpFromToken: true);
                                            if (clipDetails != null)
                                                if (!String.IsNullOrEmpty(clipDetails.Url))
                                                {
                                                    ReturnCode.StatusCode = (int)ErrorCodes.Success;
                                                    ReturnCode.StatusMessage = "OK";
                                                    ReturnCode.info = clipDetails.Url;
                                                    return this.Json(ReturnCode, JsonRequestBehavior.AllowGet);
                                                }
                                        }
                                        ReturnCode.StatusMessage = "Clip not available.";
                                        return this.Json(ReturnCode, JsonRequestBehavior.AllowGet);
                                    }
                                    ReturnCode.StatusMessage = "Asset not available.";
                                    return this.Json(ReturnCode, JsonRequestBehavior.AllowGet);
                                }
                            }
                            ReturnCode.StatusMessage = "Access to this clip is restricted.";
                            return this.Json(ReturnCode, JsonRequestBehavior.AllowGet);
                        }
                    }
                    ReturnCode.StatusMessage = "Episode does not exist.";
                }
            }
            catch (Exception e) { ReturnCode.StatusMessage = e.Message; }
            return this.Json(ReturnCode, JsonRequestBehavior.AllowGet);
        }
        public static CheckSubscriptionReturnObject HasActiveSubscriptionBasedOnCategoryId(User user, IEnumerable<int> categoryIds, DateTime? registDt = null, string CountryCodeViaIp = null)
        {
            var returnObject = new CheckSubscriptionReturnObject() { HasSubscription = false, Within5DaysOrLess = false, IsFreeEntitlement = false };
            try
            {
                SortedSet<int> completeCategoryIds = new SortedSet<int>();
                if (registDt == null)
                    registDt = DateTime.Now;
                if (user != null)
                {
                    if (user.Entitlements != null)
                    {
                        if (user.Entitlements.Count(e => e.EndDate > registDt) > 0)
                        {
                            foreach (var entitlement in user.Entitlements)
                            {
                                if (entitlement.EndDate > registDt)
                                {
                                    if (entitlement is PackageEntitlement)
                                    {
                                        var pkgEntitlement = (PackageEntitlement)entitlement;
                                        var showIds = pkgEntitlement.Package.GetAllOnlineShowIds(user.CountryCode);
                                        completeCategoryIds.UnionWith(showIds);
                                    }
                                    else if (entitlement is ShowEntitlement)
                                    {
                                        var showEntitlement = (ShowEntitlement)entitlement;
                                        completeCategoryIds.Add(showEntitlement.CategoryId);
                                    }

                                    if (completeCategoryIds.Intersect(categoryIds).Count() > 0)
                                    {
                                        returnObject.HasSubscription = true;
                                        if (returnObject.SubscriptionEndDate == null)
                                            returnObject.SubscriptionEndDate = entitlement.EndDate;
                                        else if (returnObject.SubscriptionEndDate < entitlement.EndDate)
                                            returnObject.SubscriptionEndDate = entitlement.EndDate;
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    //after checking entitlements and user still has no subscription
                    //fallback is to  check if shows are available on anonymous and default logged in packages
                    if (!returnObject.HasSubscription)
                    {
                        SortedSet<int> listOfPackageIds = new SortedSet<int>();
                        listOfPackageIds.Add(GlobalConfig.LoggedInDefaultPackageId);
                        listOfPackageIds.Add(GlobalConfig.AnonymousDefaultPackageId);

                        var context = new IPTV2Entities();
                        var offering = context.Offerings.Find(GlobalConfig.offeringId);
                        var packages = offering.Packages.Where(p => listOfPackageIds.Contains(p.PackageId));
                        if (packages != null)
                        {
                            if (packages.Count() > 0)
                            {
                                foreach (var package in packages)
                                {
                                    completeCategoryIds.UnionWith(package.GetAllOnlineShowIds(user.CountryCode));
                                }
                            }
                            returnObject.HasSubscription = completeCategoryIds.Intersect(categoryIds).Count() > 0;
                            returnObject.IsFreeEntitlement = returnObject.HasSubscription;
                        }
                    }

                    if (returnObject.SubscriptionEndDate != null && registDt != null)
                    {
                        if (returnObject.SubscriptionEndDate.Value.Subtract((DateTime)registDt).TotalDays <= 3)
                        {
                            returnObject.NumberOfDaysLeft = Convert.ToInt32(returnObject.SubscriptionEndDate.Value.Subtract((DateTime)registDt).TotalDays);
                            returnObject.Within5DaysOrLess = true;
                        }
                    }

                }
                else //Logged out, check default anonymous package
                {
                    var context = new IPTV2Entities();
                    var offering = context.Offerings.Find(GlobalConfig.offeringId);
                    var package = offering.Packages.FirstOrDefault(p => p.PackageId == GlobalConfig.AnonymousDefaultPackageId);
                    var listOfShows = package.GetAllOnlineShowIds(CountryCodeViaIp);
                    returnObject.HasSubscription = listOfShows.Intersect(categoryIds).Count() > 0;
                    returnObject.IsFreeEntitlement = returnObject.HasSubscription;
                }
            }
            catch (Exception e) { MyUtility.LogException(e); }
            return returnObject;
        }
        public static CheckSubscriptionReturnObject HasActiveSubscriptionBasedOnProducts(IPTV2Entities context, User user, Offering offering, Product product)
        {
            var returnObject = new CheckSubscriptionReturnObject() { HasSubscription = false, Within5DaysOrLess = false };
            try
            {
                var subProducts = user.GetSubscribedProducts(offering);
                if (product != null)
                {
                    if (product is SubscriptionProduct)
                    {
                        if (product is PackageSubscriptionProduct)
                        {
                            var packageProduct = (PackageSubscriptionProduct)product;
                            returnObject.SubscriptionEndDate = user.PackageEntitlements.FirstOrDefault(u => u.PackageId == packageProduct.Packages.First().PackageId).EndDate;
                        }
                        else if (product is ShowSubscriptionProduct)
                        {
                            var showProduct = (ShowSubscriptionProduct)product;
                            returnObject.SubscriptionEndDate = user.ShowEntitlements.FirstOrDefault(u => u.CategoryId == showProduct.Categories.First().CategoryId).EndDate;
                        }
                        returnObject.HasSubscription = subProducts.Select(s => s.ProductId).Contains(product.ProductId);
                    }
                }

            }
            catch (Exception e) { MyUtility.LogException(e); }
            return returnObject;
        }
 public JsonResult IsEpisodeEntitled(int id)
 {
     var result = new CheckSubscriptionReturnObject() { HasSubscription = false, Within5DaysOrLess = false };
     var context = new IPTV2Entities();
     var CacheDuration = new TimeSpan(0, GlobalConfig.GetParentShowsForEpisodeCacheDuration, 0);
     var episode = context.Episodes.FirstOrDefault(e => e.EpisodeId == id);
     var parentCategories = episode.GetParentShows(CacheDuration);
     var registDt = DateTime.Now;
     if (User.Identity.IsAuthenticated)
     {
         var UserId = new Guid(User.Identity.Name);
         var user = context.Users.FirstOrDefault(u => u.UserId == UserId);
         result = ContextHelper.HasActiveSubscriptionBasedOnCategoryId(user, parentCategories, registDt);
     }
     else
         result = ContextHelper.HasActiveSubscriptionBasedOnCategoryId(null, parentCategories, registDt);
     return this.Json(result, JsonRequestBehavior.AllowGet);
 }
        //[RequireHttps]
        public JsonResult Feed01()
        {
            var ReturnCode = new ServiceReturnType()
            {
                StatusCode = (int)ErrorCodes.UnknownError,
                StatusMessage = String.Empty
            };

            //if (!Request.IsLocal)
            //    if (!GlobalConfig.isUAT)
            //        if (!Request.IsAjaxRequest())
            //        {
            //            ReturnCode.StatusCode = (int)ErrorCodes.IsInvalidRequest;
            //            ReturnCode.StatusMessage = "Request is not valid.";
            //            return this.Json(ReturnCode, JsonRequestBehavior.AllowGet);
            //        }

            int id = GlobalConfig.TFCtvMobileAirEpisodeId;
            DateTime registDt = DateTime.Now;
            try
            {
                string CountryCode = MyUtility.GetCountryCodeViaIpAddressWithoutProxy();

                if (MyUtility.IsWhiteListed(String.Empty))
                    CountryCode = "HK";
                else
                {
                    try
                    {
                        var requestingIp = Request.GetUserHostAddressFromCloudflare();
                        var whiteListedIp = GlobalConfig.IpWhiteList.Split(',');
                        if (whiteListedIp.Contains(requestingIp) && GlobalConfig.isUAT)
                            CountryCode = "HK";
                    }
                    catch (Exception) { }
                }

                using (var context = new IPTV2Entities())
                {
                    Episode episode = context.Episodes.FirstOrDefault(e => e.EpisodeId == id);
                    if (episode != null)
                    {
                        if (episode.OnlineStatusId == GlobalConfig.Visible && episode.OnlineStartDate < registDt && episode.OnlineEndDate > registDt)
                        {
                            var CacheDuration = new TimeSpan(0, GlobalConfig.GetParentShowsForEpisodeCacheDuration, 0);
                            var parentCategories = episode.GetParentShows(CacheDuration);
                            Offering offering = context.Offerings.Find(GlobalConfig.offeringId);
                            AkamaiFlowPlayerPluginClipDetails clipDetails = null;
                            //var ShowListBasedOnCountryCode = ContextHelper.GetAllShowsBasedOnCountryCode(context, CountryCode, true, offering);
                            var HasActiveSubscriptionBasedOnCategoryId = new CheckSubscriptionReturnObject() { HasSubscription = false, Within5DaysOrLess = false };
                            if (parentCategories != null)
                                HasActiveSubscriptionBasedOnCategoryId = ContextHelper.HasActiveSubscriptionBasedOnCategoryId(null, parentCategories, registDt, CountryCode);
                            if (HasActiveSubscriptionBasedOnCategoryId.HasSubscription)
                            {
                                var premiumAsset = episode.PremiumAssets.LastOrDefault();
                                if (premiumAsset != null)
                                {
                                    Asset asset = premiumAsset.Asset;
                                    if (asset != null)
                                    {
                                        int assetId = asset == null ? 0 : asset.AssetId;
                                        if (episode.IsLiveChannelActive == true) //isLiveEvent
                                        {
                                            if (!ContextHelper.DoesEpisodeHaveIosCdnReferenceBasedOAsset(premiumAsset))
                                            {
                                                if (Request.Browser.IsMobileDevice)
                                                {
                                                    ReturnCode.StatusCode = (int)ErrorCodes.IsNotAvailableOnMobileDevices;
                                                    ReturnCode.StatusMessage = "This stream is not available on this device";
                                                    return this.Json(ReturnCode, JsonRequestBehavior.AllowGet);
                                                }
                                            }

                                            clipDetails = Helpers.Akamai.GetAkamaiLiveEventClipDetails_M3U8(episode.EpisodeId, assetId, Request, User, true, CountryCodeOverride: CountryCode, RemoveIpFromToken: true);
                                            if (clipDetails != null)
                                                if (!String.IsNullOrEmpty(clipDetails.Url))
                                                {
                                                    ReturnCode.StatusCode = (int)ErrorCodes.Success;
                                                    ReturnCode.StatusMessage = "OK";
                                                    ReturnCode.info = clipDetails.Url;
                                                    return this.Json(ReturnCode, JsonRequestBehavior.AllowGet);
                                                }
                                        }
                                        ReturnCode.StatusMessage = "Clip not available.";
                                        return this.Json(ReturnCode, JsonRequestBehavior.AllowGet);
                                    }
                                    ReturnCode.StatusMessage = "Asset not available.";
                                    return this.Json(ReturnCode, JsonRequestBehavior.AllowGet);
                                }
                            }
                            ReturnCode.StatusMessage = "Access to this clip is restricted.";
                            return this.Json(ReturnCode, JsonRequestBehavior.AllowGet);
                        }
                    }
                    ReturnCode.StatusMessage = "Episode does not exist.";
                }
            }
            catch (Exception e) { ReturnCode.StatusMessage = e.Message; }
            return this.Json(ReturnCode, JsonRequestBehavior.AllowGet);
        }