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

namespace Apewer.Source
{

    /// <summary>表示在解析数据模型过程中发生的错误。</summary>
    [Serializable]
    public class ModelException : Exception
    {

        const string EmptyMessage = "(无消息)";

        string _msg = null;
        Type _model = null;

        /// <summary>获取描述当前异常的消息。</summary>
        public override string Message { get => _msg; }

        /// <summary>数据模型的类型。</summary>
        public Type Model { get => _model; }

        /// <summary>初始化 <see cref="ModelException"/> 类的新实例。</summary>
        /// <param name="message">描述当前异常的消息。</param>
        /// <param name="model">数据模型的类型。</param>
        public ModelException(string message, Type model = null)
        {
            _msg = string.IsNullOrEmpty(message) ? EmptyMessage : message;
            _model = model;
        }

        /// <summary>表示数据模型类型无效的异常实例。</summary>
        public static ArgumentNullException InvalidType() => new ArgumentNullException("数据模型的类型无效。");

        /// <summary>表示数据模型结构无效的异常实例。</summary>
        /// <param name="model">数据模型。</param>
        public static ModelException InvalidStructure(Type model)
        {
            if (model == null) return new ModelException("数据模型的类型无效。");
            return new ModelException($"类型 <{model.Name}> 的数据模型结构无效。");
        }

        /// <summary>表示表名称无效的异常实例。</summary>
        /// <param name="model">数据模型。</param>
        public static ModelException InvalidTableName(Type model)
        {
            if (model == null) return new ModelException("数据模型的类型无效。");
            return new ModelException($"类型 <{model.Name}> 不包含表名称。");
        }

        /// <summary>表示丢失了 Key 字段的异常实例。</summary>
        /// <param name="model">数据模型。</param>
        public static ModelException MissingKey(Type model)
        {
            if (model == null) return new ModelException("数据模型的类型无效。");
            return new ModelException($"类型 <{model.Name}> 不包含 Key 属性的字段。");
        }

        /// <summary>表示丢失了 Flag 字段的异常实例。</summary>
        /// <param name="model">数据模型。</param>
        public static ModelException MissingFlag(Type model)
        {
            if (model == null) return new ModelException("数据模型的类型无效。");
            return new ModelException($"类型 <{model.Name}> 不包含 Flag 属性的字段。");
        }

        /// <summary>表示表名称无效的异常实例。</summary>
        public static ModelException InvalidTableName<TModel>() => InvalidTableName(typeof(TModel));

        /// <summary>表示丢失了 Key 字段的异常实例。</summary>
        public static ModelException MissingKey<TModel>() => MissingKey(typeof(TModel));

        /// <summary>表示丢失了 Flag 字段的异常实例。</summary>
        public static ModelException MissingFlag<TModel>() => MissingFlag(typeof(TModel));

    }

    /// <summary>表示在解析数据模型过程中发生的错误。</summary>
    [Serializable]
    public class ModelException<TModel> : ModelException
    {

        /// <summary>初始化 <see cref="ModelException"/> 类的新实例。</summary>
        /// <param name="message">描述当前异常的消息。</param>
        public ModelException(string message) : base(message, typeof(TModel)) { }

        /// <summary>表示表名称无效的异常实例。</summary>
        public static ModelException InvalidTableName() => InvalidTableName(typeof(TModel));

        /// <summary>表示丢失了 Key 字段的异常实例。</summary>
        public static ModelException MissingKey() => MissingKey(typeof(TModel));

        /// <summary>表示丢失了 Flag 字段的异常实例。</summary>
        public static ModelException MissingFlag() => MissingFlag(typeof(TModel));

    }

}