using System;
using System.Collections.Generic;
using System.Text;

namespace InABox.Core
{
    /// <summary>
    /// Base interface for all "Posters" - classes that define the means of processing an <see cref="IPostable"/> <see cref="Entity"/>.
    /// There is little point in directly implementing this; rather, one should implement a subinterface.
    /// The functionality of any <see cref="IPoster{TEntity,TSettings}"/> is essentially the default functionality, and, based on the subinterface implemented,
    /// will be scriptable.
    /// </summary>
    /// <typeparam name="TEntity">The type of entity that this poster can process.</typeparam>
    /// <typeparam name="TSettings">The <see cref="PosterSettings"/> specific to this type of poster.</typeparam>
    public interface IPoster<TEntity, TSettings>
        where TEntity : Entity, IPostable, IRemotable, IPersistent, new()
        where TSettings : PosterSettings
    {
        TSettings Settings { get; set; }
    }

    /// <summary>
    /// An interface to declare that an <see cref="IPoster{TEntity, TSettings}"/> provides a means to determine if a given <typeparamref name="TEntity"/>
    /// needs to be reposted. This function is to be called on the server side when a <typeparamref name="TEntity"/> is saved.
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    public interface IAutoRefreshPoster<TEntity, TAutoRefresher>
        where TAutoRefresher : IAutoRefresher<TEntity>
    {
    }

    public interface IAutoRefresher<TEntity>
    {
        /// <summary>
        /// Return <see langword="true"/> if <paramref name="entity"/> should be reposted, which will update its <see cref="IPostable.PostedStatus"/> to
        /// <see cref="PostedStatus.RequiresRepost"/>.
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        bool ShouldRepost(TEntity entity);
    }

    public interface IGlobalSettingsPoster
    {
        public IGlobalPosterSettings GlobalSettings { get; set; }
    }

    /// <summary>
    /// Declares that an <see cref="IPoster{TEntity, TSettings}"/> has global, entity-independent settings.
    /// </summary>
    public interface IGlobalSettingsPoster<TGlobalSettings> : IGlobalSettingsPoster
        where TGlobalSettings : BaseObject, IGlobalPosterSettings
    {
        public new TGlobalSettings GlobalSettings { get; set; }

        IGlobalPosterSettings IGlobalSettingsPoster.GlobalSettings
        {
            get => GlobalSettings;
            set
            {
                if(value is TGlobalSettings settings)
                {
                    GlobalSettings = settings;
                }
            }
        }
    }
}
