namespace UtilitariosNet.Clases.Comunes
{
    using System;
    using System.Collections.Generic;
    using System.Configuration;
    using System.Diagnostics;
    using System.Reflection;
    using UtilitariosNet.Constantes;
    using UtilitariosNet.Recursos;

    public class UtilidadesComunes
    {
        /// <summary>
        /// Obtiene el identificador de la aplicacion
        /// </summary>
        /// <returns>El Identificador unico del aplicativo</returns>
        public static Guid TraerIdAplicacion()
        {
            if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings[RecursosUtilitarios.IdAplicacion]))
            {
                return new Guid(ConfigurationManager.AppSettings[RecursosUtilitarios.IdAplicacion]);
            }
            else
            {
                throw new Exception(string.Format(RecursosUtilitarios.ParametroNoConfiguradoCorrectamente, RecursosUtilitarios.IdAplicacion));
            }
        }

        public static string TraerUrlServicioRedis()
        {
            if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings[RecursosUtilitarios.UrlDatabaseRedis]))
            {
                return ConfigurationManager.AppSettings[RecursosUtilitarios.UrlDatabaseRedis].ToString();
            }
            else
            {
                throw new Exception(string.Format(RecursosUtilitarios.ParametroNoConfiguradoCorrectamente, RecursosUtilitarios.UrlDatabaseRedis));
            }
        }

        public string ObtenerMetodoEjecucion(Type tipoClase)
        {
            try
            {
                List<string> metodosAIgnorar = new List<string>();

                if (tipoClase.EsNulo())
                {
                    metodosAIgnorar = ConstantesComunes.METODOSAIGNORAR;
                }

                string resultado = string.Concat((tipoClase.EsNulo() ? string.Empty : tipoClase.FullName));
                StackTrace traza = new StackTrace(false);

                bool esElMetodo, esElMetodoOpcional;

                foreach (StackFrame marco in traza.GetFrames())
                {
                    MethodBase metodo = marco.GetMethod();

                    if (tipoClase.EsNulo())
                    {
                        esElMetodo = metodosAIgnorar.Find(m => metodo.Name.Contains(m)).EsNulo();
                        esElMetodoOpcional = metodo.DeclaringType.Name.StartsWith(ConstantesComunes.METODOEMPIEZACON);
                    }
                    else
                    {
                        esElMetodo = esElMetodoOpcional = metodo.DeclaringType == tipoClase && tipoClase.IsAssignableFrom(metodo.DeclaringType);
                    }

                    if (esElMetodo)
                    {
                        resultado = string.Concat(metodo.DeclaringType.FullName, ConstantesComunes.PUNTO, metodo.Name, ConstantesComunes.ABRIRPARENTESIS, ConstantesComunes.CERRARPARENTESIS);

                        if (!esElMetodoOpcional)
                        {
                            break;
                        }
                    }
                }

                return resultado;
            }
            catch (Exception)
            {
                return ConstantesComunes.METODOVACIO;
            }
        }
    }
}