﻿#region License

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#endregion

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using Gremlin.Net.Process.Traversal;

namespace Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation
{
    public class TraversalParser
    {
        private static readonly IDictionary<string, Func<GraphTraversalSource, ITraversal>> FixedTranslations = 
            new Dictionary<string, Func<GraphTraversalSource, ITraversal>>
            {
                { "g.V().fold().count(Scope.local)", g => g.V().Fold().Count(Scope.Local)}
            };

        private static readonly Regex RegexNumeric =
            new Regex(@"\d+(\.\d+)?(?:l|f)?", RegexOptions.Compiled | RegexOptions.IgnoreCase);

        private static readonly Regex RegexEnum = new Regex(@"\w+\.\w+", RegexOptions.Compiled);

        private static readonly Regex RegexIO = new Regex(@"IO.\w+", RegexOptions.Compiled);

        private static readonly Regex RegexWithOptions = new Regex(@"WithOptions.\w+", RegexOptions.Compiled);

        private static readonly Regex RegexParam = new Regex(@"\w+", RegexOptions.Compiled);
        
        private static readonly HashSet<Type> NumericTypes = new HashSet<Type>
        {
            typeof(int), typeof(long), typeof(double), typeof(float), typeof(short), typeof(decimal), typeof(byte)
        };

        internal static ITraversal GetTraversal(string traversalText, GraphTraversalSource g,
                                                IDictionary<string, object> contextParameterValues)
        {
            if (!FixedTranslations.TryGetValue(traversalText, out var traversalBuilder))
            {
                var tokens = ParseTraversal(traversalText);
                return GetTraversalFromTokens(tokens, g, contextParameterValues, traversalText);
            }
            return traversalBuilder(g);
        }

        internal static ITraversal GetTraversalFromTokens(IList<Token> tokens, GraphTraversalSource g,
                                                          IDictionary<string, object> contextParameterValues,
                                                          string traversalText)
        {
            object instance;
            Type instanceType;
            if (tokens[0].Name == "g")
            {
                instance = g;
                instanceType = g.GetType();
            }
            else if (tokens[0].Name == "__")
            {
                instance = null;
                instanceType = typeof(__);
            }
            else
            {
                throw BuildException(traversalText);
            }
            for (var i = 1; i < tokens.Count; i++)
            {
                var token = tokens[i];
                token.SetContextParameterValues(contextParameterValues);
                var name = GetCsharpName(token.Name);
                var methods = instanceType.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)
                    .Where(m => m.Name == name).ToList();
                var method = GetClosestMethod(methods, token.Parameters);
                if (method == null)
                {
                    throw new InvalidOperationException($"Traversal method '{tokens[i].Name}' not found for testing");
                }
                var parameterValues = BuildParameters(method, token, out var genericParameters);
                method = BuildGenericMethod(method, genericParameters, parameterValues);
                instance = method.Invoke(instance, parameterValues);
                instanceType = instance.GetType();
            }
            return (ITraversal) instance;
        }

        /// <summary>
        /// Find the method that supports the amount of parameters provided
        /// </summary>
        private static MethodInfo GetClosestMethod(IList<MethodInfo> methods, IList<ITokenParameter> tokenParameters)
        {
            if (methods.Count == 0)
            {
                return null;
            }
            if (methods.Count == 1)
            {
                return methods[0];
            }
            var ordered = methods.OrderBy(m => m.GetParameters().Length);
            if (tokenParameters.Count == 0)
            {
                return ordered.First();
            }
            MethodInfo lastMethod = null;
            var compatibleMethods = new Dictionary<int, MethodInfo>();
            foreach (var method in ordered)
            {
                var methodParameters = method.GetParameters();
                var requiredParameters = methodParameters.Length;
                if (requiredParameters > 0 && IsParamsArray(methodParameters.Last()))
                {
                    // Params array can be not provided
                    requiredParameters--;
                }
                if (tokenParameters.Count < requiredParameters)
                {
                    continue;
                }
                lastMethod = method;
                var matched = true;
                var exactMatches = 0;
                for (var i = 0; i < tokenParameters.Count; i++)
                {
                    if (methodParameters.Length <= i)
                    {
                        // The method contains less parameters (and no params array) than provided
                        matched = false;
                        break;
                    }
                    var methodParameter = methodParameters[i];
                    var tokenParameterType = tokenParameters[i].GetParameterType();
                    // Match either the same parameter type
                    matched = methodParameter.ParameterType == tokenParameterType;
                    if (matched)
                    {
                        exactMatches++;
                    }
                    else if (IsParamsArray(methodParameter))
                    {
                        matched = methodParameter.ParameterType == typeof(object[]) ||
                                  methodParameter.ParameterType.GetElementType() == tokenParameterType;
                        // The method has params array, no further parameters are going to be defined
                        break;
                    }
                    else
                    {
                        if (IsNumeric(methodParameter.ParameterType) && IsNumeric(tokenParameterType))
                        {
                            // Acount for implicit conversion of numeric values as an exact match 
                            exactMatches++;
                        }
                        else if (!methodParameter.ParameterType.GetTypeInfo().IsAssignableFrom(tokenParameterType))
                        {
                            // Not a match
                            break;
                        }
                        // Is assignable to the parameter type
                        matched = true;
                    }
                }
                if (matched)
                {
                    compatibleMethods[exactMatches] = method;
                }
            }
            // Attempt to use the method with the higher number of matches or the last one
            return compatibleMethods.OrderByDescending(kv => kv.Key).Select(kv => kv.Value).FirstOrDefault() ??
                   lastMethod;
        }

        private static bool IsNumeric(Type t) => NumericTypes.Contains(t);

        private static bool IsParamsArray(ParameterInfo methodParameter)
        {
            return methodParameter.IsDefined(typeof(ParamArrayAttribute), false);
        }

        private static MethodInfo BuildGenericMethod(MethodInfo method, IDictionary<string, Type> genericParameters,
                                                     object[] parameterValues)
        {
            if (!method.IsGenericMethod)
            {
                return method;
            }
            var genericArgs = method.GetGenericArguments();
            var types = new Type[genericArgs.Length];
            for (var i = 0; i < genericArgs.Length; i++)
            {
                var name = genericArgs[i].Name;
                Type type;
                if (!genericParameters.TryGetValue(name, out type))
                {
                    // Try to infer it from the name based on modern graph
                    type = ModernGraphTypeInformation.GetTypeArguments(method, parameterValues, i);
                }
                if (type == null)
                {
                    throw new InvalidOperationException(
                        $"Can not build traversal to test as '{method.Name}()' method is generic and type '{name}'" +
                         " can not be inferred");
                }
                types[i] = type;
            }
            return method.MakeGenericMethod(types);
        }

        private static object[] BuildParameters(MethodInfo method, Token token,
                                                out IDictionary<string, Type> genericParameterTypes)
        {
            var paramsInfo = method.GetParameters();
            var parameters = new object[paramsInfo.Length];
            genericParameterTypes = new Dictionary<string, Type>();
            for (var i = 0; i < paramsInfo.Length; i++)
            {
                var info = paramsInfo[i];
                object value = null;
                if (token.Parameters.Count > i)
                {
                    var tokenParameter = token.Parameters[i];
                    value =  tokenParameter.GetValue();
                    if (info.ParameterType.IsGenericParameter)
                    {
                        // We've provided a value for parameter of a generic type, we can infer the
                        // type of the generic argument based on the parameter.
                        // For example, in the case of `Constant<E2>(E2 value)`
                        // if we have the type of value we have the type of E2. 
                        genericParameterTypes.Add(info.ParameterType.Name, tokenParameter.GetParameterType());
                    }
                    else if (IsParamsArray(info) && info.ParameterType.GetElementType().IsGenericParameter)
                    {
                        // Its a method where the type parameter comes from an params Array
                        // e.g., Inject<S>(params S[] value)
                        genericParameterTypes.Add(info.ParameterType.GetElementType().Name,
                            tokenParameter.GetParameterType());
                    }

                    if (info.ParameterType != tokenParameter.GetParameterType() && IsNumeric(info.ParameterType) &&
                        IsNumeric(tokenParameter.GetParameterType()))
                    {
                        // Numeric conversion
                        value = Convert.ChangeType(value, info.ParameterType);
                    }
                }

                if (IsParamsArray(info))
                {
                    // For `params type[] value` we should provide an empty array
                    if (value == null)
                    {
                        // An empty array
                        value = Array.CreateInstance(info.ParameterType.GetElementType(), 0);
                    }
                    else if (!value.GetType().IsArray)
                    {
                        // An array with the parameter values
                        // No more method parameters after this one
                        var elementType = info.ParameterType.GetElementType();

                        if (elementType.IsGenericParameter)
                        {
                            // The Array element type is generic, so we use type of the value to specify it
                            elementType = value.GetType();
                        }

                        var arr = Array.CreateInstance(elementType, token.Parameters.Count - i);
                        arr.SetValue(value, 0);
                        for (var j = 1; j < token.Parameters.Count - i; j++)
                        {
                            arr.SetValue(token.Parameters[i + j].GetValue(), j);
                        }
                        value = arr;
                    }
                }
                parameters[i] = value ?? GetDefault(info.ParameterType);
            }
            return parameters;
        }

        public static object GetDefault(Type type)
        {
            return type.GetTypeInfo().IsValueType ? Activator.CreateInstance(type) : null;
        }

        internal static string GetCsharpName(string part)
        {
            // Transform to PascalCasing and remove the parenthesis
            return char.ToUpper(part[0]) + part.Substring(1);
        }

        private static Exception BuildException(string traversalText)
        {
            return new InvalidOperationException($"Can not build a traversal to test from '{traversalText}'");
        }

        internal static IList<Token> ParseTraversal(string traversalText)
        {
            var index = 0;
            return ParseTokens(traversalText, ref index);
        }

        private static IList<Token> ParseTokens(string text, ref int i)
        {
            // Parser issue: quotes are not normalized
            text = text.Replace("\\\"", "\"");
            var result = new List<Token>();
            var startIndex = i;
            var parsing = ParsingPart.Name;
            var parameters = new List<ITokenParameter>();
            string name = null;
            while (i < text.Length)
            {
                switch (text[i])
                {
                    case '.':
                        if (parsing == ParsingPart.Name)
                        {
                            // The previous token was an object property, not a method
                            result.Add(new Token(text.Substring(startIndex, i - startIndex)));
                        }
                        startIndex = i + 1;
                        parameters = new List<ITokenParameter>();
                        parsing = ParsingPart.Name;
                        break;
                    case '(':
                    {
                        name = text.Substring(startIndex, i - startIndex);
                        parsing = ParsingPart.StartParameters;
                        // Start parsing from the next index
                        i++;
                        var param = ParseParameter(text, ref i);
                        if (param == null)
                        {
                            // The next character was a ')', empty params
                            // Evaluate the current position
                            continue;
                        }
                        parameters.Add(param);
                        break;
                    }
                    case ',' when parsing == ParsingPart.StartParameters && text.Length > i + 1 && text[i+1] != ' ':
                    case ' ' when parsing == ParsingPart.StartParameters && text.Length > i + 1 && text[i+1] != ' ' &&
                                  text[i+1] != ')':
                    {
                        i++;
                        var param = ParseParameter(text, ref i);
                        if (param == null)
                        {
                            // The next character was a ')', empty params
                            // Evaluate the current position
                            continue;
                        }
                        parameters.Add(param);
                        break;
                    }
                    case ',' when parsing != ParsingPart.StartParameters:
                    case ')' when parsing != ParsingPart.StartParameters:
                        // The current nested object already ended
                        if (parsing == ParsingPart.Name)
                        {
                            // The previous token was an object property, not a method and finished
                            result.Add(new Token(text.Substring(startIndex, i - startIndex)));
                        }
                        i--;
                        return result;
                    case ')':
                        parsing = ParsingPart.EndParameters;
                        result.Add(new Token(name, parameters));
                        break;
                }
                i++;
            }
            if (parsing == ParsingPart.Name)
            {
                // The previous token was an object property, not a method and finished
                result.Add(new Token(text.Substring(startIndex, i - startIndex)));
            }
            return result;
        }

        private static ITokenParameter ParseParameter(string text, ref int i)
        {
            var firstChar = text[i];
            while (char.IsWhiteSpace(firstChar))
            {
                firstChar = text[++i];
            }
            if (firstChar == ')')
            {
                return null;
            }
            if (firstChar == '"' || firstChar == '\'')
            {
                return StringParameter.Parse(text, firstChar, ref i);
            }
            if (char.IsDigit(firstChar))
            {
                return ParseNumber(text, ref i);
            }
            if (text.Length >= i + 3 && text.Substring(i, 3) == "__.")
            {
                var startIndex = i;
                var tokens = ParseTokens(text, ref i);
                return new StaticTraversalParameter(tokens, text.Substring(startIndex, i - startIndex));
            }
            if (text.Length >= i + 6 && text.Substring(i, 6) == "TextP.")
            {
                return new TextPParameter(ParseTokens(text, ref i));
            }
            if (text.Substring(i, 2).StartsWith("P."))
            {
                return new PParameter(ParseTokens(text, ref i));
            }
            var parameterText = text.Substring(i, text.IndexOf(')', i) - i);
            var separatorIndex = parameterText.IndexOf(',');
            if (separatorIndex >= 0)
            {
                parameterText = parameterText.Substring(0, separatorIndex);
            }
            parameterText = parameterText.Trim();
            if (parameterText == "")
            {
                return null;
            }
            if (parameterText == "true" || parameterText == "false")
            {
                i += parameterText.Length - 1;
                return LiteralParameter.Create(Convert.ToBoolean(parameterText));
            }
            if (RegexIO.IsMatch(parameterText))
            {
                i += parameterText.Length - 1;
                return new IOParameter(parameterText);
            }
            if (RegexWithOptions.IsMatch(parameterText))
            {
                i += parameterText.Length - 1;
                return new WithOptionsParameter(parameterText);
            }
            if (RegexEnum.IsMatch(parameterText))
            {
                i += parameterText.Length - 1;
                return new TraversalEnumParameter(parameterText);
            }
            if (RegexParam.IsMatch(parameterText))
            {
                i += parameterText.Length - 1;
                return new ContextBasedParameter(parameterText);
            }
            throw new NotSupportedException($"Parameter {parameterText} not supported");
        }
        
        private static ITokenParameter ParseNumber(string text, ref int i)
        {
            var match = RegexNumeric.Match(text, i);
            if (!match.Success)
            {
                throw new InvalidOperationException(
                    $"Could not parse numeric value from the beginning of {text.Substring(i)}");
            }
            var numericText = match.Value.ToUpper();
            i += match.Value.Length - 1;
            if (numericText.EndsWith("L"))
            {
                return LiteralParameter.Create(Convert.ToInt64(match.Value.Substring(0, match.Value.Length - 1)));
            }
            if (numericText.EndsWith("F"))
            {
                return LiteralParameter.Create(Convert.ToSingle(match.Value.Substring(0, match.Value.Length - 1),
                    CultureInfo.InvariantCulture));
            }
            if (match.Groups[1].Value != "")
            {
                // Captured text with the decimal separator
                return LiteralParameter.Create(Convert.ToDecimal(match.Value, CultureInfo.InvariantCulture));
            }
            return LiteralParameter.Create(Convert.ToInt32(match.Value));
        }
        
        private enum ParsingPart
        {
            Name,
            StartParameters,
            EndParameters
        }
    }
}
