private Expr GenerateTermsObj(Type collectionType)
        {
            List <Expr> exprs = new List <Expr>();

            foreach (var term in Terms)
            {
                if (term.GetType() == typeof(string))
                {
                    FaunaFieldAttribute fieldAttribute = collectionType.GetProperty(term.ToString())?.GetCustomAttribute <FaunaFieldAttribute>();
                    if (fieldAttribute == null)
                    {
                        fieldAttribute = collectionType.GetField(term.ToString())?.GetCustomAttribute <FaunaFieldAttribute>();
                    }
                    exprs.Add(Obj("field", Arr("data", fieldAttribute?.Name ?? term.ToString())));
                }
                else if (term.GetType() == typeof(FaunaTermType))
                {
                    FaunaTermType faunaTermType = (FaunaTermType)Enum.Parse(typeof(FaunaTermType), term.ToString());
                    if (faunaTermType == FaunaTermType.Ref)
                    {
                        exprs.Add(Obj("field", "ref"));
                    }
                    else if (faunaTermType == FaunaTermType.Ts)
                    {
                        exprs.Add(Obj("field", "ts"));
                    }
                }
            }

            return(Arr(exprs.ToArray()));
        }
        public string GenerateIndexName(Type collectionType)
        {
            FaunaCollection collection = collectionType.GetCustomAttribute <FaunaCollection>();

            string s = string.Empty;

            if (Values == null ||
                (Values != null && Values.Length == 0) ||
                (Values != null && Values.Length == 1 && Values[0].GetType() == typeof(FaunaValueType) && (FaunaValueType)Enum.Parse(typeof(FaunaValueType), Values[0].ToString()) == FaunaValueType.Ref))
            {
                s += $"{collection?.Name ?? collectionType.Name}";
            }
            else
            {
                int i = 0;
                foreach (object val in Values)
                {
                    if (i > 0)
                    {
                        s += "_";
                    }

                    if (val.GetType() != typeof(FaunaValueType))
                    {
                        if (val.GetType() == typeof(IndexOrdering))
                        {
                            IndexOrdering orderingType = (IndexOrdering)Enum.Parse(typeof(IndexOrdering), val.ToString());
                            if (orderingType == IndexOrdering.Reverse)
                            {
                                s += $"reverse";
                            }
                        }
                        else
                        {
                            FaunaFieldAttribute fieldAttribute = collectionType.GetProperty(val.ToString())?.GetCustomAttribute <FaunaFieldAttribute>();
                            if (fieldAttribute == null)
                            {
                                fieldAttribute = collectionType.GetField(val.ToString())?.GetCustomAttribute <FaunaFieldAttribute>();
                            }

                            s += $"{fieldAttribute?.Name ?? val.ToString()}";
                        }
                    }
                    else
                    {
                        FaunaValueType faunaValueType = (FaunaValueType)Enum.Parse(typeof(FaunaValueType), val.ToString());
                        if (faunaValueType == FaunaValueType.Ref)
                        {
                            s += $"{collection?.Name ?? collectionType.Name}";
                        }
                        else if (faunaValueType == FaunaValueType.Ts)
                        {
                            s += $"ts";
                        }
                    }
                    i++;
                }
            }
            s += "_by";
            if (Terms != null)
            {
                for (int i = 0; i < Terms.Length; i++)
                {
                    object term = Terms[i];
                    s += "_";
                    if (term.GetType() != typeof(FaunaValueType))
                    {
                        FaunaFieldAttribute fieldAttribute = collectionType.GetProperty(term.ToString())?.GetCustomAttribute <FaunaFieldAttribute>();
                        if (fieldAttribute == null)
                        {
                            fieldAttribute = collectionType.GetField(term.ToString())?.GetCustomAttribute <FaunaFieldAttribute>();
                        }
                        s += $"{fieldAttribute?.Name ?? term.ToString()}";
                    }
                    else
                    {
                        FaunaTermType faunaValueType = (FaunaTermType)Enum.Parse(typeof(FaunaTermType), term.ToString());
                        if (faunaValueType == FaunaTermType.Ref)
                        {
                            s += $"{collection?.Name ?? collectionType.Name}";
                        }
                        else if (faunaValueType == FaunaTermType.Ts)
                        {
                            s += $"ts";
                        }
                    }
                }
            }
            else
            {
                //TODO figure out what to call it when there are no terms
            }
            return(s);
        }
        private Expr GenerateValuesObj(Type collectionType)
        {
            List <Expr> exprs = new List <Expr>();
            int         i     = 0;

            foreach (var value in Values)
            {
                bool isReverse = false;
                if (Values.Length > i + 1)
                {
                    if (Values[i + 1].GetType() == typeof(IndexOrdering) && (IndexOrdering)Enum.Parse(typeof(IndexOrdering), Values[i + 1].ToString()) == IndexOrdering.Reverse)
                    {
                        isReverse = true;
                    }
                }

                if (value.GetType() == typeof(string))
                {
                    FaunaFieldAttribute fieldAttribute = collectionType.GetProperty(value.ToString())?.GetCustomAttribute <FaunaFieldAttribute>();
                    if (fieldAttribute == null)
                    {
                        fieldAttribute = collectionType.GetField(value.ToString())?.GetCustomAttribute <FaunaFieldAttribute>();
                    }
                    if (isReverse)
                    {
                        exprs.Add(Obj("field", Arr("data", fieldAttribute?.Name ?? value.ToString()), "reverse", true));
                    }
                    else
                    {
                        exprs.Add(Obj("field", Arr("data", fieldAttribute?.Name ?? value.ToString())));
                    }
                }
                else if (value.GetType() == typeof(FaunaTermType))
                {
                    FaunaValueType faunaValueType = (FaunaValueType)Enum.Parse(typeof(FaunaValueType), value.ToString());
                    if (faunaValueType == FaunaValueType.Ref)
                    {
                        if (isReverse)
                        {
                            exprs.Add(Obj("field", "ref", "reverse", true));
                        }
                        else
                        {
                            exprs.Add(Obj("field", "ref"));
                        }
                    }
                    else if (faunaValueType == FaunaValueType.Ts)
                    {
                        if (isReverse)
                        {
                            exprs.Add(Obj("field", "ts", "reverse", true));
                        }
                        else
                        {
                            exprs.Add(Obj("field", "ts"));
                        }
                    }
                }
                i++;
            }
            return(Arr(exprs.ToArray()));
        }