using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Edge.Core.Processor.Dispatcher.Attributes
{
    /// <summary>
    /// Providing the jsonSchemas for method's or ctor's parameters.
    /// </summary>
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor, AllowMultiple = false)]
    public class ParamsJsonSchemas : Attribute
    {
        /// <summary>
        /// the jsonSchemas persisted in a resource file.
        /// </summary>
        /// <param name="schemaEmbededResourceName">the resource file name, only the '.json' file extension can be omit.</param>
        public ParamsJsonSchemas(string schemaEmbededResourceName)
        {
            if (schemaEmbededResourceName.ToLower().EndsWith(".json"))
                this.SchemaEmbededResourceName = schemaEmbededResourceName.Trim();
            else
                this.SchemaEmbededResourceName = schemaEmbededResourceName.Trim() + ".json";
        }

        /// <summary>
        /// the json schema's are defined with inline strings.
        /// </summary>
        /// <param name="schemaStrings">one for each parameter</param>
        public ParamsJsonSchemas(string[] schemaStrings)
        {
            this.SchemaStrings = schemaStrings;
        }

        ///// <summary>
        ///// Not specify jsonSchema, system will auto generate json schema for parameters
        ///// </summary>
        //public ParamsJsonSchemas() { }

        /// <summary>
        /// </summary>
        public string SchemaEmbededResourceName { get; private set; }

        /// <summary>
        /// Array of Json Schema strings, each array element is for a ctor parameter.
        /// </summary>
        public string[] SchemaStrings { get; private set; }
    }

    /// <summary>
    /// Declare the parts that the current host parts(marked this attribute) required.
    ///     Mostly used in DeviceHandler that require combine with specific MessageBase, 
    ///     MessageCutter, MessageParser, Communicator, or DeviceProcessor, to construct a Processor.
    /// </summary>
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
    public class MetaPartsRequired : Attribute
    {
        /// <summary>
        /// </summary>
        /// <param name="requiredPartsType">other parts's type</param>
        public MetaPartsRequired(Type requiredPartsType)
        {
            this.RequiredPartsType = requiredPartsType;
        }

        public Type RequiredPartsType { get; private set; }

        //public MetaPartsRequired(bool isSystemInternalComponent, string description)
        //{
        //    this.IsSystemInternalComponent = isSystemInternalComponent;
        //    this.Description = description;
        //}

        ///// <summary>
        ///// Use this Ctor for the purpose of declaring some info for host class itself.
        ///// </summary>
        ///// <param name="description">the purpose the host class for, may used for generate in UI</param>
        //public MetaPartsRequired(string description) : this(false, description)
        //{
        //}

        //public bool IsSystemInternalComponent { get; private set; }
        //public string Description { get; private set; }

        /// <summary>
        /// This value will be used in instantiate the PartsRequired.
        /// Each element in Array is a json value for corresponding ctor parameter that will be used to instantiate parts' instance.
        ///     like: [1, "helloWorld", "{"name":"Elsa","age":"10"}"]
        /// </summary>
        public string[] DefaultCtorParamsJsonStrings { get; set; } = new string[] { };
    }

    /// <summary>
    /// Used to declare readable info for DeviceHandler or AppProcessor.
    /// </summary>
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
    public class MetaPartsDescriptor : Attribute
    {
        /// <summary>
        /// The readable content for decorated class.
        /// </summary>
        /// <param name="displayName">text that support multi-language, follow the sample string-> lang-zh-cn:X加油机lang-en-us:Xdispenser</param>
        /// <param name="description">text that support multi-language, follow the sample string-> lang-zh-cn:用于驱动加油机lang-en-us:Used for driven dispenser</param>
        public MetaPartsDescriptor(string displayName, string description)
        {
            this.DisplayName = displayName;
            this.Description = description;
        }

        /// <summary>
        /// The readable content for decorated class, with category specified(by add tags).
        /// </summary>
        /// <param name="displayName">text that support multi-language, follow the sample string-> lang-zh-cn:X加油机lang-en-us:Xdispenser</param>
        /// <param name="description">text that support multi-language, follow the sample string-> lang-zh-cn:用于驱动加油机lang-en-us:Used for driven dispenser</param>
        /// <param name="tags">the category of the target, like: Pump, Atg, Terminal and ect. Multi-language is support here, if multi-lang string value is provided, then should at least provide english version of the value, which will be used for filtering(show me api feature).
        public MetaPartsDescriptor(string displayName, string description, string[] tags)
        {
            this.DisplayName = displayName;
            this.Description = description;
            this.Tags = tags;
        }

        public string[] Tags { get; private set; }

        public string DisplayName { get; private set; }
        public string Description { get; private set; }

        /// <summary>
        /// Gets or sets the value to indicates the decorated class(Either DeviceHanlder or AppProcessor) 
        /// is a build-in and has no business logic module, this kind of module is always used for
        /// providing special management purpose APIs.
        /// </summary>
        public bool IsSystemInternalComponent { get; set; }

        /// <summary>
        /// if no concrete parameter specified, this default value will be pass into Parts(defined by Type) to try 
        ///     to instantiate the Parts instance.
        /// Each element in Array is a json value for corresponding ctor parameter that will be used to instantiate parts' instance.
        ///     like: [1, "helloWorld", "{"name":"Peppa","age":"10"}"]
        /// </summary>
        public string[] DefaultCtorParamsJsonStrings { get; set; }
    }
}
