using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;

namespace InABox.Core.Postable
{
    #region BaseExceptions

    public class BasePosterException : Exception
    {
        public BasePosterException() : base() { }

        public BasePosterException(string message) : base(message) { }
    }
    public class MissingSettingException : BasePosterException
    {
        public Type SettingsType { get; }

        public string Setting { get; set; }

        public MissingSettingException(Type settingsType, string setting): base($"Missing setting '{setting}'")
        {
            SettingsType = settingsType;
            Setting = setting;
        }
    }

    public class MissingSettingException<T> : MissingSettingException
    {
        public MissingSettingException(Expression<Func<T, object?>> setting) : base(typeof(T), CoreUtils.GetFullPropertyName(setting, ".")) { }
    }

    public class MissingSettingsException : BasePosterException
    {
        public Type PostableType { get; }

        public MissingSettingsException(Type postableType) : base($"No PostableSettings for ${postableType}")
        {
            PostableType = postableType;
        }
    }

    #endregion

    #region PostExceptions

    public class PostException : BasePosterException
    {
        public PostException() : base() { }

        public PostException(string message) : base(message) { }
    }

    public class EmptyPostException : PostException
    {
        public EmptyPostException() { }
    }

    public class PostFailedMessageException : PostException
    {
        public PostFailedMessageException(string message): base(message) { }
    }

    public class RepostedException : PostException
    {
        public RepostedException() : base("Cannot process an item twice.")
        {
        }
    }
    public class PostCancelledException : PostException
    {
        public PostCancelledException() : base("Processing cancelled")
        {
        }
    }

    #endregion

    #region PullExceptions

    public class PullException : BasePosterException
    {
        public PullException() : base() { }

        public PullException(string message) : base(message) { }
    }

    public class PullCancelledException : PullException
    {
        public PullCancelledException(): base("Import cancelled") { }
    }

    public class PullFailedMessageException : PullException
    {
        public PullFailedMessageException(string message): base(message) { }
    }

    public class InvalidPullerException : PullException
    {
        public Type PostableType { get; set; }

        public Type? PosterType { get; set; }

        public InvalidPullerException(Type postableType)
            : base($"Cannot import {postableType.Name}")
        {
            PostableType = postableType;
            PosterType = null;
        }

        public InvalidPullerException(Type postableType, Type posterType)
            : base($"Cannot import {postableType.Name} with {posterType.GetCaptionOrNull(true) ?? posterType.Name}")
        {
            PostableType = postableType;
            PosterType = posterType;
        }
    }

    #endregion
}
