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

namespace WayneCloud.Models
{
    /// <summary>
    /// Aconfiguration group can help to group a serial of configs together, which typically used for a same purpose.
    /// 
    /// e.g.: A client side is retrieving configs, it may specify a Group name rather than a specific configId,
    ///     then the client may get serials of configs.
    /// </summary>
    public class ConfigurationGroup
    {
        public Guid Id { get; set; }

        /// <summary>
        /// Gets or sets the name of configuration group.
        /// </summary>
        public string Name { get; set; }

        public string Description { get; set; }
        public DateTime CreatedServerTime { get; set; }
    }

    public enum ConfigValueType
    {
        // most likely the json or xml content.
        PlainText,
        // saved as base 64 string for binary.
        File
    }



    /// <summary>
    /// used for host a concrete configuration for a logical entity, could be a Business Unit, or a Device.
    /// </summary>
    public class Configuration
    {
        public Guid Id { get; set; }

        /// <summary>
        /// Gets or sets the owner id who owns this configuration value.
        /// could be a Device, or a BusinessUnit, then this value could be a DeviceSerialNumber, or a BU's guid.
        /// </summary>
        public string OwnerId { get; set; }

        public ConfigValueType ValueType { get; set; }

        /// <summary>
        /// Gets or sets the name of this configuration, unique for each Owner
        /// </summary>
        public string Name { get; set; }

        public virtual Guid? GroupId { get; set; }
        /// <summary>
        /// Gets or sets the group of this configuration, a configuration group can help to
        /// group a serial of configs together, which typically used for a same purpose.
        /// 
        /// e.g.: A client side is retrieving configs, it may specify a Group name rather than a specific configId,
        ///     then the client may get serials of configs.
        /// </summary>
        public virtual ConfigurationGroup Group { get; set; }

        public virtual Guid? TemplateId { get; set; }
        public virtual ConfigurationTemplate Template { get; set; }

        public string Description { get; set; }

        /// <summary>
        /// Gets or sets if enable this configuration.
        /// </summary>
        public bool Enabled { get; set; }

        /// <summary>
        /// --!!!!!!---> IF xml content, make sure no space between nodes
        /// Gets or sets the concreate configuration values,
        /// Use base64 encode string for faciliates the binary content.
        /// or json(xml) for other cases.
        /// </summary>
        public string Value { get; set; }

        public virtual List<ConfigurationFile> Files { get; set; }

        public DateTime CreatedClientTime { get; set; }
        public DateTime CreatedServerTime { get; set; }
        public virtual Guid CreatedByUser { get; set; }
    }
    public class ConfigurationTemplate
    {
        public Guid Id { get; set; }

        public string Name { get; set; }

        public string Description { get; set; }

        public virtual DateTime? CreatedDateTime { get; set; }

        public ConfigurationTemplateEncoding Encoding { get; set; }
        /// <summary>
        /// front-end read this for showing a UI
        /// </summary>
        public string UITemplate { get; set; }
        public virtual List<ConfigurationTemplateResource> Resources { get; set; }
        /// <summary>
        /// back-end read concrete configuration value and combine with this template, to generate final required format config, which end-point can 
        /// consume directly.
        /// </summary>
        //public string DataParseTemplate { get; set; }

        //public ParemeterTypeEnum ParameterType { get; set; }

        public virtual Guid? ConfigurationTemplateGroupId { get; set; }

        public virtual ConfigurationTemplateGroup TemplateGroup { get; set; }
    }
    public class ConfigurationTemplateGroup
    {
        public Guid Id { get; set; }

        public string Name { get; set; }

        public string Description { get; set; }

        public virtual DateTime? CreatedDateTime { get; set; }

        //public virtual List<ConfigurationTemplate> ConfigurationTemplates { get; set; }
    }
    public class ConfigurationTemplateResource
    {
        public Guid Id { get; set; }

        /// <summary>
        /// Gets or sets the name of this Resource
        /// </summary>
        public string Name { get; set; }


        public virtual Guid? ConfigurationTemplateId { get; set; }

        public virtual ConfigurationTemplate Template { get; set; }

        public string Value { get; set; }

        public string Description { get; set; }

        public DateTime CreatedDateTime { get; set; }

        /// <summary>
        /// the encoding type of this resouce is persisted
        /// </summary>
        public ConfigurationTemplateEncoding Encoding { get; set; }
    }
    public enum ConfigurationTemplateEncoding { Base64Html, Base64Binary, Html, PlainText }
    public class ConfigurationFile
    {
        public Guid Id { get; set; }

        public virtual Guid ConfigurationId { get; set; }

        public virtual ConfigDescription Configuration { get; set; }

        public virtual string Name { get; set; }

        /// <summary>
        /// Original full file name, like abcd.txt
        /// </summary>
        public virtual string FullName { get; set; }

        public virtual long Length { get; set; }

        public virtual string ContentHash { get; set; }

        public virtual byte[] Value { get; set; }

        public DateTime CreatedServerTime { get; set; }
    }

    public class ConfigFileDescription
    {
        public Guid Id { get; set; }

        public virtual string Name { get; set; }

        /// <summary>
        /// Original full file name, like abcd.txt
        /// </summary>
        public virtual string FullName { get; set; }

        public virtual long Length { get; set; }

        public virtual string ContentHash { get; set; }

        public DateTime CreatedServerTime { get; set; }
    }

    /// <summary>
    /// Description for a config
    /// </summary>
    public class ConfigDescription
    {
        /// <summary>
        /// Unique id for a config.
        /// </summary>
        public Guid ConfigId { get; set; }

        /// <summary>
        /// the owner id of the config, could be a BusinessUnit Guid or Device's SerialNumber
        /// </summary>
        public string OwnerId { get; set; }

        /// <summary>
        /// the type of the config
        /// </summary>
        public ConfigValueType ValueType { get; set; }

        /// <summary>
        /// Name of the config
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// user friendly message for help understand the purpose of this config
        /// </summary>
        public string Description { get; set; }

        /// <summary>
        /// Created server time
        /// </summary>
        public DateTime CreatedTime { get; set; }

        public IEnumerable<ConfigFileDescription> ConfigFileDescriptions { get; set; }

        /// <summary>
        /// MD5 hash for concrete config value, used to detect if a config had been changed.
        /// </summary>
        public string ValueMD5 { get; set; }

        public string GroupName { get; set; }
    }

}
