import sys
import re
import yaml
import os
from lib.ClienteLinux import obter_cliente_linux
import tempfile
import subprocess

def obter_dados():
    return {

    }

def ajustar_enderecos_backends(
    endereco_arquivo_config,
    configuracoes,
    substituir=False
):
    conteudo_arquivo = ""

    with open(endereco_arquivo_config, 'r') as arquivo:
        conteudo_arquivo = arquivo.read()

    conteudo_arquivo = re.sub(
        pattern=r"\$HOST_ENTERPRISE",
        repl=[x for x in configuracoes["api-gateway"]["backends"] if x["nome"] == "ApiEnterprise"][0]["host"],
        string=conteudo_arquivo
    )

    conteudo_arquivo = re.sub(
        pattern=r"\$PORTA_ENTERPRISE",
        repl=[x for x in configuracoes["api-gateway"]["backends"] if x["nome"] == "ApiEnterprise"][0]["porta"],
        string=conteudo_arquivo
    )

    conteudo_arquivo = re.sub(
        pattern=r"\$HOST_REST",
        repl=[x for x in configuracoes["api-gateway"]["backends"] if x["nome"] == "Rest"][0]["host"],
        string=conteudo_arquivo
    )

    conteudo_arquivo = re.sub(
        pattern=r"\$PORTA_REST",
        repl=[x for x in configuracoes["api-gateway"]["backends"] if x["nome"] == "Rest"][0]["porta"],
        string=conteudo_arquivo
    )

    if not substituir:

        return conteudo_arquivo
    
    with open(endereco_arquivo_config, 'w') as arquivo:
        arquivo.write(conteudo_arquivo)

    return None



def criar_conteudo_docker_compose(configuracoes):
    docker_compose = {
        'version': '3.9',
        'services': {
            'nginx': {
                'container_name': 'api-gateway',
                'image' : 'nginx:1.26.0',
                'ports': [
                    f"{configuracoes['api-gateway']['porta']}:80"
                ],
                'volumes': [
                    "./config/mapeamentos-padrao.conf:/etc/nginx/conf.d/mapeamentos-padrao.conf",
                    "./config/api-backends.conf:/etc/nginx/conf.d/api-backends.conf",
                    "./docker-entrypoint.d/40-excluir-default.conf.sh:/docker-entrypoint.d/40-excluir-default.conf.sh",
                ]
            }
        }
    }

    return docker_compose



def escrever_conteudo_docker_compose(conteudo, endereco_arquivo):
    with open(endereco_arquivo, 'w') as arquivo:
        yaml.dump(conteudo, arquivo, sort_keys=False)

        

def executar_configuracao_completa(configuracoes, diretorio_scripts_implantacao):
    diretorio_api_gateway = os.path.join(diretorio_scripts_implantacao,  "api-gateway")
    cliente_linux = obter_cliente_linux(configuracoes=configuracoes)

    usuario = configuracoes['acessos']['servidorLinux']['usuario']
    

    if not os.path.exists(diretorio_api_gateway):
        os.mkdir(diretorio_api_gateway)

    cliente_linux.executar_comando(f"mkdir -p /home/{usuario}/api-gateway")
    cliente_linux.executar_comando(f"mkdir -p /home/{usuario}/api-gateway/config")
    cliente_linux.executar_comando(f"mkdir -p /home/{usuario}/api-gateway/docker-entrypoint.d")
    
    
    def ajustar_enderecos_backends():
        endereco_arquivo_config = f'/home/{usuario}/api-gateway/config/api-backends.conf'

        cliente_linux.executar_comando(r"sed -i 's,\$HOST_ENTERPRISE,{host_enterprise},g' {arquivo_config}".format(
            host_enterprise = [x for x in configuracoes["api-gateway"]["backends"] if x["nome"] == "ApiEnterprise"][0]["host"],
            arquivo_config = endereco_arquivo_config
        ))

        
        cliente_linux.executar_comando(r"sed -i 's,\$PORTA_ENTERPRISE,{host_enterprise},g' {arquivo_config}".format(
            host_enterprise = [x for x in configuracoes["api-gateway"]["backends"] if x["nome"] == "ApiEnterprise"][0]["porta"],
            arquivo_config = endereco_arquivo_config
        ))

        cliente_linux.executar_comando(r"sed -i 's,\$HOST_REST,{host_enterprise},g' {arquivo_config}".format(
            host_enterprise = [x for x in configuracoes["api-gateway"]["backends"] if x["nome"] == "Rest"][0]["host"],
            arquivo_config = endereco_arquivo_config
        ))

        cliente_linux.executar_comando(r"sed -i 's,\$PORTA_REST,{host_enterprise},g' {arquivo_config}".format(
            host_enterprise = [x for x in configuracoes["api-gateway"]["backends"] if x["nome"] == "Rest"][0]["porta"],
            arquivo_config = endereco_arquivo_config
        ))

    def copiar_arquivos_config():
        
        arquivos_config = []

        for root,dir,files in os.walk(os.path.join(diretorio_api_gateway, "config")):
            for file in files:
                if file.endswith(".conf"):
                    arquivos_config.append(os.path.join(root, file))

        

        for arquivo in arquivos_config:
            cliente_linux.copiar_arquivo(
                arquivo, 
                f'/home/{usuario}/api-gateway/config/{os.path.basename(arquivo)}')
            
    def copiar_docker_entrypoint_scripts():
        endereco_script = os.path.join(diretorio_api_gateway, "docker-entrypoint.d", "40-excluir-default.conf.sh")
        dos2unix = os.path.join(diretorio_scripts_implantacao, "dos2unix.exe")

        subprocess.run([dos2unix, endereco_script])
        
        cliente_linux.copiar_arquivo(
            endereco_script,
            f'/home/{usuario}/api-gateway/docker-entrypoint.d/40-excluir-default.conf.sh'
        )

        cliente_linux.executar_comando(f"chmod +x /home/{usuario}/api-gateway/docker-entrypoint.d/40-excluir-default.conf.sh")

    def criar_docker_compose():
        conteudo_docker_compose = criar_conteudo_docker_compose(configuracoes)

        docker_compose_temporario = tempfile.NamedTemporaryFile(delete=False,suffix=".yml").name

        escrever_conteudo_docker_compose(conteudo_docker_compose, docker_compose_temporario)

        cliente_linux.copiar_arquivo(docker_compose_temporario, f'/home/{usuario}/api-gateway/docker-compose.yml')

    def parar_e_subir_container():
        cliente_linux.executar_comando(f"docker rm -f api-gateway")
        cliente_linux.executar_comando(f"docker compose -f /home/{usuario}/api-gateway/docker-compose.yml down")
        cliente_linux.executar_comando(f"docker compose -f /home/{usuario}/api-gateway/docker-compose.yml pull")
        cliente_linux.executar_comando(f"docker compose -f /home/{usuario}/api-gateway/docker-compose.yml up -d")
        
    def ajustar_mapeamento():
        diretorio_api_gateway = os.path.join(diretorio_scripts_implantacao,  "api-gateway")
        diretorio_perfis = os.path.join(diretorio_api_gateway, "perfis")
        
        cliente_linux.executar_comando(
            f"rm -f /home/{usuario}/api-gateway/config/mapeamentos-padrao.conf"
        )
        configurarParaPesquisaProduto = configuracoes["api-gateway"]["configurarParaPesquisaProduto"]
        configurarParaColetaPrecos = configuracoes["api-gateway"]["configurarParaColetaPrecos"]
        configurarParaLiquidacaoAutomaticaBoleto = configuracoes["api-gateway"]["configurarParaLiquidacaoAutomaticaBoleto"]
        perfil_pesquisa_produto_path = os.path.join(diretorio_perfis, "mapeamento-pesquisa-produto.conf")
        with open(perfil_pesquisa_produto_path, 'r', encoding='utf-8') as arquivo:
            conteudoPerfilPesquisaProduto = ''.join('    ' + line for line in arquivo)

        perfil_coleta_precos_path = os.path.join(diretorio_perfis, "mapeamento-coleta-precos.conf")
        with open(perfil_coleta_precos_path, 'r', encoding='utf-8') as arquivo:
            conteudoPerfilColetaPrecos = ''.join('    ' + line for line in arquivo)
            
        with open(os.path.join(diretorio_perfis, "mapeamento-liquidacao-automatica-boleto.conf"), 'r', encoding='utf-8') as arquivo:
            conteudoPerfilLiquidacaoAutomaticaBoleto = ''.join('    ' + line for line in arquivo)
        
        mapeamentoPadrao = """server {
    listen 80;
"""   
        if configurarParaPesquisaProduto:
            mapeamentoPadrao += conteudoPerfilPesquisaProduto
        
        if configurarParaColetaPrecos:
            mapeamentoPadrao += conteudoPerfilColetaPrecos
            
        if configurarParaLiquidacaoAutomaticaBoleto:
            mapeamentoPadrao += conteudoPerfilLiquidacaoAutomaticaBoleto
        mapeamentoPadrao += "}\n"
       
        temp_map = tempfile.NamedTemporaryFile(delete=False, suffix=".conf")
        with open(temp_map.name, 'w', encoding='utf-8') as f:
            f.write(mapeamentoPadrao)

        cliente_linux.copiar_arquivo(
            temp_map.name,
            f'/home/{usuario}/api-gateway/config/mapeamentos-padrao.conf'
        )

        # # clean up
        # os.remove(temp_map.name)

    copiar_arquivos_config()
    ajustar_mapeamento()
    copiar_docker_entrypoint_scripts()
    ajustar_enderecos_backends()
    criar_docker_compose()
    parar_e_subir_container()
    
