using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Authentication;
using System.Text;
using System.Threading.Tasks;
using Winbooks.TORM.OM;

namespace Winbooks.Apis.Services
{
    public class ValidateClass
    {
        public static bool ValidateWbObject(BaseOM wbObject)
        {
            Type objectType = wbObject.GetType();
            bool result = true;
            if (wbObject.MandatoryField != null)
            {
                foreach (MandatoryField mandatoryField in wbObject.MandatoryField)
                {
                    PropertyInfo property = objectType.GetProperty(mandatoryField.FieldName);
                    // if mandatory field is Guid 
                    //__case : not have involve object=> value must != Guid.Empty
                    //__case : have involve object 
                    //_______value !=Guid.Empty or ______ involve object != null => validate involve object
                    //if mandatory field is not Guid => value must be != null
                    if (property != null && mandatoryField.FieldType == typeof(Guid))
                    {
                        var propertyValue = (Guid)property.GetValue(wbObject);
                        if (propertyValue == Guid.Empty)
                        {
                            if (string.IsNullOrEmpty(mandatoryField.InvolveObject))
                            {
                                throw new ArgumentNullException(mandatoryField.FieldName + " of " + objectType.Name);
                            }
                            else
                            {
                                // get propterty is object involve
                                PropertyInfo propertyObjectInvolve = objectType.GetProperty(mandatoryField.InvolveObject);
                                if (propertyObjectInvolve != null && propertyObjectInvolve.GetValue(wbObject) == null)
                                {
                                    throw new ArgumentNullException(mandatoryField.FieldName + " of " + objectType.Name);
                                }
                                else
                                {
                                    if (propertyObjectInvolve != null)
                                    {
                                        var container = propertyObjectInvolve.GetValue(wbObject);
                                        if (container != null &&
                                            container.GetType().IsSubclassOf(typeof(BaseOM))
                                            )
                                        {
                                            result &= ValidateWbObject((BaseOM)container);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        if (property != null && property.GetValue(wbObject) == null)
                        {
                            throw new ArgumentNullException(mandatoryField.FieldName + " of " + objectType.Name);
                        }
                    }
                }
            }
            return result;
        }

        public static bool ValidateListWbObject(IEnumerable<BaseOM> LstWbObjects)
        {
            bool result = true;
            if (LstWbObjects != null && LstWbObjects.Any())
            {
                foreach (BaseOM baseOM in LstWbObjects)
                {
                    result &= ValidateWbObject(baseOM);
                }
            }
            return result;
        }
    }
}
