﻿#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 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)
            {
                lastMethod = method;
                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;
                }
                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.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 (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
        }
    }
}