/*
 * SMAC API
 *
 * SMAC ASP.NET Core Web API
 *
 * The version of the OpenAPI document: v1
 * Generated by: https://github.com/openapitools/openapi-generator.git
 */


using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.IO;
using System.Runtime.Serialization;
using System.Text;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using JsonSubTypes;
using System.ComponentModel.DataAnnotations;
using OpenAPIDateConverter = Org.OpenAPITools.Client.OpenAPIDateConverter;

namespace Org.OpenAPITools.Model
{
    /// <summary>
    /// A date time rule. The date and time are in UTC.
    /// </summary>
    [DataContract(Name = "DateTimeRule")]
    [JsonConverter(typeof(JsonSubtypes), "Type")]
    [JsonSubtypes.KnownSubType(typeof(DateTimeRule), "DateTimeRule")]
    [JsonSubtypes.KnownSubType(typeof(EmailRule), "EmailRule")]
    [JsonSubtypes.KnownSubType(typeof(LocationRule), "LocationRule")]
    [JsonSubtypes.KnownSubType(typeof(ScanOptionRule), "ScanOptionRule")]
    [JsonSubtypes.KnownSubType(typeof(UserRoleRule), "UserRoleRule")]
    public partial class DateTimeRule : BaseRule, IEquatable<DateTimeRule>, IValidatableObject
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="DateTimeRule" /> class.
        /// </summary>
        [JsonConstructorAttribute]
        protected DateTimeRule() { }
        /// <summary>
        /// Initializes a new instance of the <see cref="DateTimeRule" /> class.
        /// </summary>
        /// <param name="begDate">The begin date in UTC.</param>
        /// <param name="begTime">The begin time in UTC.</param>
        /// <param name="endDate">The end date in UTC.</param>
        /// <param name="endTime">The end time in UTC.</param>
        /// <param name="isIgnoreTimeZone">A flag indicating whether to ignore time zone. (If the flag is set, time zone is ignored for Scan API. For example, if the BegTime is set to 9am to 5pm, this rule is valid from 9am to 5pm no matter where it is scanned from.).</param>
        /// <param name="type">Defines the type of the rule (required) (default to &quot;DateTimeRule&quot;).</param>
        public DateTimeRule(DateTime? begDate = default(DateTime?), string begTime = default(string), DateTime? endDate = default(DateTime?), string endTime = default(string), bool? isIgnoreTimeZone = default(bool?), string type = "DateTimeRule") : base()
        {
            // to ensure "type" is required (not null)
            if (type == null)
            {
                throw new ArgumentNullException("type is a required property for DateTimeRule and cannot be null");
            }
            this.Type = type;
            this.BegDate = begDate;
            this.BegTime = begTime;
            this.EndDate = endDate;
            this.EndTime = endTime;
            this.IsIgnoreTimeZone = isIgnoreTimeZone;
        }

        /// <summary>
        /// The begin date in UTC
        /// </summary>
        /// <value>The begin date in UTC</value>
        [DataMember(Name = "begDate", EmitDefaultValue = true)]
        [JsonConverter(typeof(OpenAPIDateConverter))]
        public DateTime? BegDate { get; set; }

        /// <summary>
        /// The begin time in UTC
        /// </summary>
        /// <value>The begin time in UTC</value>
        [DataMember(Name = "begTime", EmitDefaultValue = true)]
        public string BegTime { get; set; }

        /// <summary>
        /// The end date in UTC
        /// </summary>
        /// <value>The end date in UTC</value>
        [DataMember(Name = "endDate", EmitDefaultValue = true)]
        [JsonConverter(typeof(OpenAPIDateConverter))]
        public DateTime? EndDate { get; set; }

        /// <summary>
        /// The end time in UTC
        /// </summary>
        /// <value>The end time in UTC</value>
        [DataMember(Name = "endTime", EmitDefaultValue = true)]
        public string EndTime { get; set; }

        /// <summary>
        /// A flag indicating whether to ignore time zone. (If the flag is set, time zone is ignored for Scan API. For example, if the BegTime is set to 9am to 5pm, this rule is valid from 9am to 5pm no matter where it is scanned from.)
        /// </summary>
        /// <value>A flag indicating whether to ignore time zone. (If the flag is set, time zone is ignored for Scan API. For example, if the BegTime is set to 9am to 5pm, this rule is valid from 9am to 5pm no matter where it is scanned from.)</value>
        [DataMember(Name = "isIgnoreTimeZone", EmitDefaultValue = true)]
        public bool? IsIgnoreTimeZone { get; set; }

        /// <summary>
        /// Defines the type of the rule
        /// </summary>
        /// <value>Defines the type of the rule</value>
        [DataMember(Name = "type", IsRequired = true, EmitDefaultValue = true)]
        public string Type { get; set; }

        /// <summary>
        /// Returns the string presentation of the object
        /// </summary>
        /// <returns>String presentation of the object</returns>
        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("class DateTimeRule {\n");
            sb.Append("  ").Append(base.ToString().Replace("\n", "\n  ")).Append("\n");
            sb.Append("  BegDate: ").Append(BegDate).Append("\n");
            sb.Append("  BegTime: ").Append(BegTime).Append("\n");
            sb.Append("  EndDate: ").Append(EndDate).Append("\n");
            sb.Append("  EndTime: ").Append(EndTime).Append("\n");
            sb.Append("  IsIgnoreTimeZone: ").Append(IsIgnoreTimeZone).Append("\n");
            sb.Append("  Type: ").Append(Type).Append("\n");
            sb.Append("}\n");
            return sb.ToString();
        }

        /// <summary>
        /// Returns the JSON string presentation of the object
        /// </summary>
        /// <returns>JSON string presentation of the object</returns>
        public override string ToJson()
        {
            return Newtonsoft.Json.JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.Indented);
        }

        /// <summary>
        /// Returns true if objects are equal
        /// </summary>
        /// <param name="input">Object to be compared</param>
        /// <returns>Boolean</returns>
        public override bool Equals(object input)
        {
            return this.Equals(input as DateTimeRule);
        }

        /// <summary>
        /// Returns true if DateTimeRule instances are equal
        /// </summary>
        /// <param name="input">Instance of DateTimeRule to be compared</param>
        /// <returns>Boolean</returns>
        public bool Equals(DateTimeRule input)
        {
            if (input == null)
            {
                return false;
            }
            return base.Equals(input) && 
                (
                    this.BegDate == input.BegDate ||
                    (this.BegDate != null &&
                    this.BegDate.Equals(input.BegDate))
                ) && base.Equals(input) && 
                (
                    this.BegTime == input.BegTime ||
                    (this.BegTime != null &&
                    this.BegTime.Equals(input.BegTime))
                ) && base.Equals(input) && 
                (
                    this.EndDate == input.EndDate ||
                    (this.EndDate != null &&
                    this.EndDate.Equals(input.EndDate))
                ) && base.Equals(input) && 
                (
                    this.EndTime == input.EndTime ||
                    (this.EndTime != null &&
                    this.EndTime.Equals(input.EndTime))
                ) && base.Equals(input) && 
                (
                    this.IsIgnoreTimeZone == input.IsIgnoreTimeZone ||
                    (this.IsIgnoreTimeZone != null &&
                    this.IsIgnoreTimeZone.Equals(input.IsIgnoreTimeZone))
                ) && base.Equals(input) && 
                (
                    this.Type == input.Type ||
                    (this.Type != null &&
                    this.Type.Equals(input.Type))
                );
        }

        /// <summary>
        /// Gets the hash code
        /// </summary>
        /// <returns>Hash code</returns>
        public override int GetHashCode()
        {
            unchecked // Overflow is fine, just wrap
            {
                int hashCode = base.GetHashCode();
                if (this.BegDate != null)
                {
                    hashCode = (hashCode * 59) + this.BegDate.GetHashCode();
                }
                if (this.BegTime != null)
                {
                    hashCode = (hashCode * 59) + this.BegTime.GetHashCode();
                }
                if (this.EndDate != null)
                {
                    hashCode = (hashCode * 59) + this.EndDate.GetHashCode();
                }
                if (this.EndTime != null)
                {
                    hashCode = (hashCode * 59) + this.EndTime.GetHashCode();
                }
                if (this.IsIgnoreTimeZone != null)
                {
                    hashCode = (hashCode * 59) + this.IsIgnoreTimeZone.GetHashCode();
                }
                if (this.Type != null)
                {
                    hashCode = (hashCode * 59) + this.Type.GetHashCode();
                }
                return hashCode;
            }
        }

        /// <summary>
        /// To validate all properties of the instance
        /// </summary>
        /// <param name="validationContext">Validation context</param>
        /// <returns>Validation Result</returns>
        public IEnumerable<System.ComponentModel.DataAnnotations.ValidationResult> Validate(ValidationContext validationContext)
        {
            return this.BaseValidate(validationContext);
        }

        /// <summary>
        /// To validate all properties of the instance
        /// </summary>
        /// <param name="validationContext">Validation context</param>
        /// <returns>Validation Result</returns>
        protected IEnumerable<System.ComponentModel.DataAnnotations.ValidationResult> BaseValidate(ValidationContext validationContext)
        {
            foreach (var x in base.BaseValidate(validationContext))
            {
                yield return x;
            }
            // Type (string) minLength
            if (this.Type != null && this.Type.Length < 1)
            {
                yield return new System.ComponentModel.DataAnnotations.ValidationResult("Invalid value for Type, length must be greater than 1.", new [] { "Type" });
            }

            yield break;
        }
    }

}
