namespace Generator_Class_BD.Clases.NetCore._1.Controladores.Api
{
    using Generator_Class_BD.Clases.Consultas;
    using Generator_Class_BD.Clases.Transversales;
    using Generator_Class_BD.Clases.Utilitarios;
    using System.Globalization;
    using System.Text;

    public class ClaseApi
    {
        internal static void GenerarController(string vNombreClase, string path, string TxtSolucion, string autor, string company)
        {
            StringBuilder cuerpo = new StringBuilder();

            string vNombreEntidad = vNombreClase;

            string vNombreEntidadL = vNombreEntidad.Substring(0, 1).ToLower() + vNombreEntidad.ToString().Substring(1);
            UtilitariosTransversales.EncabezadoDerechosAutor(vNombreClase + "Controller", cuerpo, autor, company);
            cuerpo.AppendFormat("namespace {0}.API.Controllers\n", TxtSolucion);
            cuerpo.Append("{\n");
            cuerpo.Append("\t" + ConstantesComunes.LibreriaSystem + "\n");
            cuerpo.Append("\t" + ConstantesComunes.LibreriaSystemCollectionsGeneric + "\n");
            cuerpo.Append("\t" + ConstantesComunes.LibreriaSystemThreadingTask + "\n");
            cuerpo.Append("\t" + ConstantesComunes.LibreriaUtilitariosNetAPIClasesEjecucion + "\n");
            cuerpo.Append("\t" + ConstantesComunes.LibreriaUtilitariosNetClasesComunesEntidades + "\n");
            cuerpo.Append("\t" + ConstantesComunes.LibreriaUtilitariosNetClasesMapeadorExtensiones + "\n");
            cuerpo.Append("\t" + string.Format(ConstantesComunes.LibreriaModelRepositorioApi, TxtSolucion) + "\n");
            cuerpo.Append("\t" + string.Format(ConstantesComunes.LibreriaAccionRepositorioIC, TxtSolucion) + "\n");
            cuerpo.Append("\t" + string.Format(ConstantesComunes.LibreriaBLRepositorioNegocio, TxtSolucion) + "\n");
            cuerpo.Append("\t" + ConstantesComunes.LibreriaMicrosoftAspNetCoreMvc + "\n");
            cuerpo.Append("\t\n");
            cuerpo.Append("\t/// <summary>\n");
            cuerpo.Append("\t/// Clase con las capaciades Rest de la entidad " + vNombreEntidad + "\n");
            cuerpo.Append("\t/// </summary>\n");
            cuerpo.AppendFormat("\t[Route(\"api/{0}\")]\n", vNombreClase);
            cuerpo.AppendFormat("\tpublic class {0}Controller : AccesoComunAPI\n", vNombreClase);
            cuerpo.Append("\t{\n");
            cuerpo.Append("\n");
            cuerpo.Append("\n");
            cuerpo.Append("\t\t/// <summary>\n");
            cuerpo.Append("\t\t/// Objeto para negocio " + vNombreEntidad + "\n");
            cuerpo.Append("\t\t/// </summary>\n");
            cuerpo.AppendFormat("\t\tprivate Lazy<I{0}NegocioAccion> negocio{0};\n", vNombreClase);
            cuerpo.Append("\n");
            cuerpo.Append("\t\t\n");

            cuerpo.Append("\t\t/// <summary>\n");
            cuerpo.AppendFormat("\t\t/// Inicializa una nueva instancia de la clase {0}Controller\n", vNombreEntidad);
            cuerpo.Append("\t\t/// </summary>\n");
            cuerpo.AppendFormat("\t\tpublic {0}Controller()\n", vNombreClase);
            cuerpo.Append("\t\t{\n");
            cuerpo.AppendFormat("\t\t\tthis.negocio{0} = new Lazy<I{0}NegocioAccion>(\n\t\t\t\t\t\t\t\t\t\t() => new {0}BL());\n", vNombreClase);
            cuerpo.Append("\t\t}\n");
            cuerpo.Append("\t\t\n");

            UtilitariosTransversales.EncabezadoMetodoConsultarLista(vNombreEntidad, cuerpo, vNombreEntidadL);
            cuerpo.Append("\t\t[HttpGet]\n");
            cuerpo.AppendFormat("\t\t[Route(\"ConsultarLista{0}\")]\n", vNombreClase);
            cuerpo.AppendFormat("\t\tpublic async Task<Respuesta<{0}>> ConsultarLista{0}()\n", vNombreClase);
            cuerpo.Append("\t\t{\n");
            cuerpo.AppendFormat("\t\t\treturn await this.EjecutarTransaccionAPI<Task<Respuesta<{0}>>, {0}Controller>(async () =>\n", vNombreEntidad);
            cuerpo.Append("\t\t\t{\n");
            cuerpo.AppendFormat("\t\t\t\treturn Mapeador.MapearObjetoPorJson<Respuesta<{0}>>(await negocio{0}.Value.ConsultarLista{0}Async());\n", vNombreClase);
            cuerpo.Append("\t\t\t});\n");
            cuerpo.Append("\t\t}\n");
            cuerpo.Append("\t\t\n");

            UtilitariosTransversales.EncabezadoMetodoConsultarLlave(vNombreEntidad, cuerpo, vNombreEntidadL);
            cuerpo.Append("\t\t[HttpPost]\n");
            cuerpo.AppendFormat("\t\t[Route(\"Consultar{0}Llave\")]\n", vNombreClase);
            cuerpo.AppendFormat("\t\tpublic async Task<Respuesta<{0}>> Consultar{0}Llave({0} {1})\n", vNombreClase, vNombreEntidadL);
            cuerpo.Append("\t\t{\n");
            cuerpo.AppendFormat("\t\t\treturn await this.EjecutarTransaccionAPI<Task<Respuesta<{0}>>, {0}Controller>(async () =>\n", vNombreEntidad);
            cuerpo.Append("\t\t\t{\n");
            cuerpo.AppendFormat("\t\t\t\treturn Mapeador.MapearObjetoPorJson<Respuesta<{0}>>(await negocio{0}.Value.Consultar{0}LlaveAsync({1}));\n", vNombreClase, vNombreEntidadL);
            cuerpo.Append("\t\t\t});\n");
            cuerpo.Append("\t\t}\n");
            cuerpo.Append("\t\t\n");

            UtilitariosTransversales.EncabezadoMetodoGuardar(vNombreEntidad, cuerpo, vNombreEntidadL);
            cuerpo.Append("\t\t[HttpPost]\n");
            cuerpo.AppendFormat("\t\t[Route(\"Guardar{0}\")]\n", vNombreClase);
            cuerpo.AppendFormat("\t\tpublic async Task<Respuesta<{0}>> Guardar{0}({0} {1})\n", vNombreClase, vNombreEntidadL);
            cuerpo.Append("\t\t{\n");
            cuerpo.AppendFormat("\t\t\treturn await this.EjecutarTransaccionAPI<Task<Respuesta<{0}>>, {0}Controller>(async () =>\n", vNombreEntidad);
            cuerpo.Append("\t\t\t{\n");
            cuerpo.AppendFormat("\t\t\t\treturn Mapeador.MapearObjetoPorJson<Respuesta<{0}>>(await negocio{0}.Value.Guardar{0}Async({1}));\n", vNombreClase, vNombreEntidadL);
            cuerpo.Append("\t\t\t});\n");
            cuerpo.Append("\t\t}\n");
            cuerpo.Append("\t\t\n");

            UtilitariosTransversales.EncabezadoMetodoEditar(vNombreEntidad, cuerpo, vNombreEntidadL);
            cuerpo.Append("\t\t[HttpPut]\n");
            cuerpo.AppendFormat("\t\t[Route(\"Editar{0}\")]\n", vNombreClase);
            cuerpo.AppendFormat("\t\tpublic async Task<Respuesta<{0}>> Editar{0}({0} {1})\n", vNombreClase, vNombreEntidadL);
            cuerpo.Append("\t\t{\n");
            cuerpo.AppendFormat("\t\t\treturn await this.EjecutarTransaccionAPI<Task<Respuesta<{0}>>, {0}Controller>(async () =>\n", vNombreEntidad);
            cuerpo.Append("\t\t\t{\n");
            cuerpo.AppendFormat("\t\t\t\treturn Mapeador.MapearObjetoPorJson<Respuesta<{0}>>(await negocio{0}.Value.Editar{0}Async({1}));\n", vNombreClase, vNombreEntidadL);
            cuerpo.Append("\t\t\t});\n");
            cuerpo.Append("\t\t}\n");
            cuerpo.Append("\t\t\n");

            UtilitariosTransversales.EncabezadoMetodoEliminar(vNombreEntidad, cuerpo, vNombreEntidadL);
            cuerpo.Append("\t\t[HttpDelete]\n");
            cuerpo.AppendFormat("\t\t[Route(\"Eliminar{0}\")]\n", vNombreClase);
            cuerpo.AppendFormat("\t\tpublic async Task<Respuesta<{0}>> Eliminar{0}({0} {1})\n", vNombreClase, vNombreEntidadL);
            cuerpo.Append("\t\t{\n");
            cuerpo.AppendFormat("\t\t\treturn await this.EjecutarTransaccionAPI<Task<Respuesta<{0}>>, {0}Controller>(async () =>\n", vNombreEntidad);
            cuerpo.Append("\t\t\t{\n");
            cuerpo.AppendFormat("\t\t\t\treturn Mapeador.MapearObjetoPorJson<Respuesta<{0}>>(await negocio{0}.Value.Eliminar{0}Async({1}));\n", vNombreClase, vNombreEntidadL);
            cuerpo.Append("\t\t\t});\n");
            cuerpo.Append("\t\t}\n");
            cuerpo.Append("\t}\n");
            cuerpo.Append("}\n");

            path = path + "\\Controllers\\" + vNombreClase;

            Util.CrearArchivo(path + "\\" + vNombreClase + "Controller.cs", path, cuerpo);
        }

        internal static void GenerarControllerConsulta(Consulta consulta, string path, TextInfo textInfo, string TxtSolucion, string autor, string company)
        {
            StringBuilder cuerpo = new StringBuilder();

            string vNombreEntidad = consulta.NombreObjeto;

            string vNombreEntidadL = vNombreEntidad.Substring(0, 1).ToLower() + vNombreEntidad.ToString().Substring(1);
            UtilitariosTransversales.EncabezadoDerechosAutor(consulta.NombreObjeto + "Controller", cuerpo, autor, company);
            cuerpo.AppendFormat("namespace {0}.API.Controllers\n", TxtSolucion);
            cuerpo.Append("{\n");
            cuerpo.Append("\t" + ConstantesComunes.LibreriaSystem + "\n");
            cuerpo.Append("\t" + ConstantesComunes.LibreriaSystemCollectionsGeneric + "\n");
            cuerpo.Append("\t" + ConstantesComunes.LibreriaSystemThreadingTask + "\n");
            cuerpo.Append("\t" + ConstantesComunes.LibreriaUtilitariosAPIClasesEjecucion + "\n");
            cuerpo.Append("\t" + ConstantesComunes.LibreriaUtilitariosClasesComunesEntidades + "\n");
            cuerpo.Append("\t" + ConstantesComunes.LibreriaUtilitariosClasesMapeadorExtensiones + "\n");
            cuerpo.Append("\t" + string.Format(ConstantesComunes.LibreriaModelRepositorioApi, TxtSolucion) + "\n");
            cuerpo.Append("\t" + string.Format(ConstantesComunes.LibreriaAccionRepositorioIC, TxtSolucion) + "\n");
            cuerpo.Append("\t" + string.Format(ConstantesComunes.LibreriaBLRepositorioNegocio, TxtSolucion) + "\n");
            cuerpo.Append("\t" + ConstantesComunes.LibreriaMicrosoftAspNetCoreMvc + "\n");
            cuerpo.Append("\t\n");
            cuerpo.Append("\t[EnableCors(origins: \"*\", headers: \"*\", methods: \"*\")]\n");
            cuerpo.AppendFormat("\t[RoutePrefix(\"api/{0}\")]\n", consulta.NombreObjeto);
            cuerpo.AppendFormat("\tpublic class {0}Controller : AccesoComunAPI\n", consulta.NombreObjeto);
            cuerpo.Append("\t{\n");
            cuerpo.Append("\n");
            cuerpo.AppendFormat("\t\tprivate Lazy<I{0}Accion> Negocio{0};\n", consulta.NombreObjeto);
            cuerpo.AppendFormat("\t\tprivate Lazy<I{0}NegocioAccion> {0}NegocioAccion;\n", consulta.NombreObjeto);
            cuerpo.Append("\t\t\n");
            cuerpo.AppendFormat("\t\tpublic {0}Controller()\n", consulta.NombreObjeto);
            cuerpo.Append("\t\t{\n");
            cuerpo.AppendFormat("\t\t\tNegocio{0} = new Lazy<I{0}Accion>(() => new {0}BL(new Lazy<I{0}Accion>(() => new {0}DAL()),\n" +
                                "                                                        new Lazy<I{0}RepositorioAccion>(() => new {0}DAL())));\n", consulta.NombreObjeto);
            cuerpo.Append("\n");
            cuerpo.AppendFormat("\t\t\t{0}NegocioAccion = new Lazy<I{0}NegocioAccion>(() => new {0}BL(new Lazy<I{0}Accion>(() => new {0}DAL()),\n" +
                                "                                                              new Lazy<I{0}RepositorioAccion>(() => new {0}DAL())));\n", consulta.NombreObjeto);
            cuerpo.Append("\t\t}\n");
            cuerpo.Append("\t\t\n");
            cuerpo.Append("\t\t///<summary>\n");
            cuerpo.Append("\t\t///Metodo de " + consulta.NombreObjeto + " para obtener una lista de " + Util.SeparadorPorMayusculas(consulta.NombreObjeto) + ".\n");
            cuerpo.Append("\t\t///</summary>\n");
            cuerpo.Append("\t\t[HttpGet]\n");
            cuerpo.AppendFormat("\t\t[Route(\"ConsultarLista{0}\")]\n", consulta.NombreObjeto);
            cuerpo.AppendFormat("\t\tpublic async Task<Respuesta<{0}>> ConsultarLista{0}()\n", consulta.NombreObjeto);
            cuerpo.Append("\t\t{\n");
            cuerpo.AppendFormat("\t\t\treturn await this.EjecutarTransaccionAPI<Task<Respuesta<{0}>>, {0}Controller>(async () =>\n", vNombreEntidad);
            cuerpo.Append("\t\t\t{\n");
            cuerpo.AppendFormat("\t\t\t\treturn Mapeador.MapearObjetoPorJson<Respuesta<{0}>>(await Negocio{0}.Value.ConsultarLista{0}Async());\n", consulta.NombreObjeto);
            cuerpo.Append("\t\t\t});\n");
            cuerpo.Append("\t\t}\n");
            cuerpo.Append("\t\t\n");
            cuerpo.Append("\t}\n");
            cuerpo.Append("}\n");

            path = path + "\\Controllers";

            Util.CrearArchivo(path + "\\" + consulta.NombreObjeto + "Controller.cs", path, cuerpo);
        }
    }
}