//------------------------------------------------------------------------------
// <copyright company="Telligent Systems">
//     Copyright (c) Telligent Systems Corporation.  All rights reserved.
// </copyright> 
//------------------------------------------------------------------------------

using System.Collections;
using System.IO;
using System.Security;
using System.Web;
using System.Web.Caching;
using CommunityServer.Components;

namespace CommunityServer.Blogs.Components
{
    /// <summary>
    /// Summary description for Weblogs.
    /// </summary>
    public class Weblogs
    {
        private Weblogs(){}

        #region CreateUpdateDelete
        public static int Update(Weblog w)
        {
            return Sections.UpdateSection(w);
        }

        public static int Add(Weblog w)
        {
            return Sections.AddSection(w);
        }

        public static void Delete(Weblog w)
        {
            Sections.DeleteSection(w);
 
			// Delete the folders
			try
			{
				WebDirectory.Delete(Globals.GetSiteUrls().Locations["weblogs"] + w.ApplicationKey) ;
			}
			catch(IOException e)
			{ new CSException(CSExceptionType.AccessDenied, "DeleteBlog: Permission to delete the folder on filesystem denied.", e).Log(); }
			catch(SecurityException e)
			{ new CSException(CSExceptionType.AccessDenied, "DeleteBlog: Permission to delete the folder on filesystem denied.", e).Log(); }
			catch { }

		}
        #endregion

        #region Weblog

		#region Weblog by BlogID
		/// <summary>
		/// Returns the Weblog specified by the ID
		/// </summary>
        public static Weblog GetWeblog(int blogID)
        {
            return GetWeblog(blogID,true);
        }

		/// <summary>
		/// Returns the Weblog specified by the ID and determines if it is served from the cache
		/// </summary>
		public static Weblog GetWeblog(int blogID, bool cacheable)
		{
			return GetWeblog(blogID,cacheable,false);
		}

		/// <summary>
		/// Returns the Weblog specified by the ID and determines if it is served from the cache
		/// </summary>
        public static Weblog GetWeblog(int blogID, bool cacheable, bool ignorpermissions)
        {
            CSContext csContext = CSContext.Current;
            Hashtable blogs = GetWeblogs(csContext,ignorpermissions,cacheable,false,true);
           
            // Return the blog
            foreach(Weblog b in blogs.Values)
                if(b.SectionID == blogID)
                    return b;

            // If we are still here, then the blog doesn't exist
			if (WeblogConfiguration.Instance().AuthenticateOnSectionNotFound)
				PermissionBase.RedirectOrExcpetion(CSExceptionType.SectionNotFound, "Weblog not found: " + blogID);
			else
				throw new CSException(CSExceptionType.SectionNotFound, "Weblog not found: " + blogID);

            return null;
        }

		#endregion

		#region Weblog by Name

		public static Weblog GetWeblog()
		{
			string appKey = CSContext.Current.ApplicationKey;
			if(appKey == null)
				appKey = WeblogConfiguration.Instance().DefautApplicationKey;

			return GetWeblog(appKey,true);
		}

		/// <summary>
		/// Returns the Weblog by applicationkey
		/// </summary>
        public static Weblog GetWeblog(string applicationKey)
        {
            return GetWeblog(applicationKey,true);
        }

		/// <summary>
		/// Returns the Weblog by applicationkey
		/// </summary>
        public static Weblog GetWeblog(string applicationKey, bool cacheable)
        {
            return GetWeblog(applicationKey,cacheable,false);
        }

		/// <summary>
		/// Returns the Weblog by applicationkey
		/// </summary>
        public static Weblog GetWeblog(string applicationKey, bool cacheable, bool ignorpermissions)
        {
            applicationKey = applicationKey.ToLower();
            CSContext csContext = CSContext.Current;
            Hashtable blogs;

            blogs = GetWeblogs(csContext,ignorpermissions,cacheable,false, true);

           
            Weblog b = blogs[applicationKey.ToLower()] as Weblog;

            if(b != null)
                return b;

            // If we are still here, then the blog doesn't exist
			if (WeblogConfiguration.Instance().AuthenticateOnSectionNotFound)
				PermissionBase.RedirectOrExcpetion(CSExceptionType.SectionNotFound, "Weblog not found: " + applicationKey);
			else
				throw new CSException(CSExceptionType.SectionNotFound, "Weblog not found: " + applicationKey);

            return null;
        }

		#endregion

        /// <summary>
        /// Returns a collection of Weblogs
        /// </summary>
        public static ArrayList GetWeblogs(bool cacheable, bool ignorePermissions, bool flush, bool filterByAggregate) 
        {
            CSContext csContext = CSContext.Current;
            ArrayList blogs = new ArrayList();
            Hashtable blogsTable;

            // Get the ForumGroups as a hashtable
            //
            blogsTable = GetWeblogs(csContext, ignorePermissions, cacheable,flush, false);

            // Convert the hashtable to an arraylist
            //
            foreach(Weblog blog in blogsTable.Values)
            if (blog.ParentID == 0 && (!filterByAggregate || blog.IsCommunityAggregated))
            {
                blogs.Add( blog );
            }

            blogs.Sort(new SectionSorter());

            return blogs;
        }

        /// <summary>
        /// Returns a collection of Weblogs
        /// </summary>
        public static ArrayList GetWeblogs(bool cacheable, bool ignorePermissions, bool flush) 
        {
            return GetWeblogs(cacheable,ignorePermissions,flush,false);
        }

        public static ArrayList GetWeblogsByGroupID(int groupID, bool cacheable, bool ignorePermissions, bool flush) 
        {
            CSContext csContext = CSContext.Current;
            ArrayList blogs = new ArrayList();
            Hashtable blogsTable;

            // Get the ForumGroups as a hashtable
            //
            blogsTable = GetWeblogs(csContext, ignorePermissions, cacheable, flush, false);

            // Convert the hashtable to an arraylist
            //
            foreach(Weblog blog in blogsTable.Values)
                if (blog.GroupID == groupID)
                    blogs.Add( blog );

            blogs.Sort(new SectionSorter());

            return blogs;
        }

        public static bool Exists(string applicationKey, int CurrentSectionID)
        {
            // Check to make sure sure it isn't a duplicate blog
            foreach(Weblog w in Weblogs.GetWeblogs(false, true, true))
                if(string.Compare(w.ApplicationKey, applicationKey, true) == 0 && w.SectionID != CurrentSectionID)
                    return true;
            return false;
        }

        public static bool CreateBlogDirectory(Weblog w)
        {
            try
            {
                WebDirectory.Create(Globals.GetSiteUrls().Locations["weblogs"] + w.ApplicationKey);
                return true;
             
            }
            catch(IOException ex)
            { new CSException(CSExceptionType.AccessDenied, "CreateBlog: Permission to add the folder on filesystem denied.", ex).Log(); }
            catch(SecurityException ex)
            { new CSException(CSExceptionType.AccessDenied, "CreateBlog: Permission to add the folder on filesystem denied.", ex).Log(); }
            catch { }

            return false;
        }


        private static readonly string blogsCacheKeyFormat = "Blogs-Site:{0}";

        public static void ResetWeblogCache()
        {
            CSCache.Remove(string.Format(blogsCacheKeyFormat,CSContext.Current.SiteSettings.SettingsID));
        }

        private static Hashtable GetWeblogs(CSContext csContext,bool ignorePermissions, bool cacheable, bool flush, bool ignoreLanguageFilter) 
        {
            Hashtable unfilteredBlogs = null;			 
            string cacheKey = string.Format(blogsCacheKeyFormat,csContext.SiteSettings.SettingsID);
			string localKey = string.Format("blogsForUser:{0}:{1}",ignorePermissions,ignoreLanguageFilter);

			#region NoCache
#if DEBUG_NOCACHE
            cacheable = false;
			flush = true;
#endif
			#endregion


			if(flush)
			{
				CSCache.Remove(cacheKey);
				csContext.Items[localKey] = null;
			}

            // Have we already fetched for this request?
            //
            unfilteredBlogs = csContext.Items[localKey] as Hashtable;
            if (unfilteredBlogs != null)
                return unfilteredBlogs;

            // Ensure it's not in the cache
            if (!cacheable)
                CSCache.Remove(cacheKey);

            // Get the raw blogs
            //
            unfilteredBlogs = CSCache.Get(cacheKey) as Hashtable;
            if ( unfilteredBlogs == null ) 
            {
                WeblogDataProvider wdp = WeblogDataProvider.Instance();
                unfilteredBlogs = wdp.GetWeblogs();

                // Cache if we can
                //
                if (cacheable)
                    CSCache.Insert(cacheKey, unfilteredBlogs, null, CSCache.MinuteFactor * 15, CacheItemPriority.High);

            } 

			if (!ignoreLanguageFilter && !ignorePermissions)
				unfilteredBlogs = Sections.FilterByLanguage(unfilteredBlogs, csContext);

            // Are we ignoring permissions?
            //
			if (ignorePermissions)
			{
				csContext.Items[localKey] = unfilteredBlogs;
				return unfilteredBlogs;
			}

            // We need to create a new hashtable
            //
            Hashtable blogs = new Hashtable();

            // Filter the list of weblogs to only show weblogs this user 
            // is allowed to see
            //
            
            foreach (Weblog w in unfilteredBlogs.Values) 
            {
                // The Weblog is added if the user can View it
                //
                if((w.IsActive || csContext.User.IsBlogAdministrator) && Permissions.ValidatePermissions( w, Permission.View,csContext.User))
                {
					blogs.Add(w.ApplicationKey, w);
                }
            }

            // Insert into request cache
            //
            csContext.Items[localKey] =  blogs;

            return blogs;

        }
        #endregion

        public static void UpdateRecentContent(int SettingsID)
        {
            WeblogDataProvider.Instance().UpdateRecentContent(SettingsID);
        }

    }

 
}
