
. $PSScriptRoot\validarComandoAnterior.ps1
. $PSScriptRoot\configuracoesMicrouniversoWeb.ps1
. $PSScriptRoot\configurarCertificadoDigital.ps1
. $PSScriptRoot\_echo.ps1
. $PSScriptRoot\criptografiaSenha.ps1

# Tipos MIME que o IIS do Windows Server 2012 / 2012 R2 nao conhece por padrao.
# Sem o tipo registrado o IIS responde 404 ao servir o arquivo e as fontes de icones
# nao carregam no front-end (ex.: .woff2 do vendas). Versoes mais novas do IIS ja trazem
# esses tipos, entao o registro abaixo e idempotente: remove a entrada antes de adicionar.
$global:muTiposMimeEstaticos = @(
    @{ extensao = ".woff";  tipo = "font/woff" },
    @{ extensao = ".woff2"; tipo = "font/woff2" }
)

function global:_mu.configurarTiposMime() {
    param(
        $appcmd
    )

    foreach ($tipoMime in $global:muTiposMimeEstaticos) {
        _echo "Registrando tipo MIME $($tipoMime.extensao) => $($tipoMime.tipo)"

        # A remocao falha quando a extensao ainda nao esta registrada. Isso e esperado e nao
        # deve interromper a instalacao, por isso o comando nao e validado.
        & $appcmd set config /section:staticContent /-"[fileExtension='$($tipoMime.extensao)']" /commit:apphost

        & $appcmd set config /section:staticContent /+"[fileExtension='$($tipoMime.extensao)',mimeType='$($tipoMime.tipo)']" /commit:apphost
        mu.validarComandoAnterior
    }
}

function global:_mu.configurarSite() {
    param(
        $configuracoes,
        $appcmd,
        $nomeServico

    )

    $servico = $configuracoes.servicos."$nomeServico"

    if (!($servico.configurar)) {
        return _echo "Servico $($servico.nomeSite) nao sera configurado"
    }

    #$diretorioBaseInstalacao = $configuracoes.enderecos.diretorioBaseInstalacao
    #$diretorioInstalacao = "$diretorioBaseInstalacao\$($servico.diretorioRelativoInstalacao)"

    $diretorioInstalacao = if ("diretorioRelativoInstalacao" -in $servico.psobject.properties.name) {
        "$($configuracoes.enderecos.diretorioBaseInstalacao)\$($servico.diretorioRelativoInstalacao)"
    } elseif ("diretorioAbsolutoInstalacao" -in $servico.psobject.properties.name) {
        $servico.diretorioAbsolutoInstalacao
    } else {
        throw "Diretorio de instalacao nao informado para $nomeServico"
    }

    $ativar32Bit = if ("ativar32Bit" -in $servico.psobject.properties.name) {$servico.ativar32Bit} else {$true}
    $tempoSleep = 1
    
    _echo "Excluindo site $($servico.nomeSite)"
    & $appcmd delete site /site.name:$($servico.nomeSite)
    Start-Sleep -Seconds $tempoSleep
    mu.validarComandoAnterior
    

    _echo "Excluindo pool $($servico.nomeSite)"
    & $appcmd delete apppool /apppool.name:$($servico.nomeSite)
    Start-Sleep -Seconds $tempoSleep
    mu.validarComandoAnterior

    _echo "Criando pool $($servico.nomeSite)"
    & $appcmd add apppool /name:$($servico.nomeSite) /managedRuntimeVersion:v4.0 /managedPipelineMode:Integrated
    Start-Sleep -Seconds $tempoSleep
    mu.validarComandoAnterior

    _echo "Adicionando site $($servico.nomeSite)"
    & $appcmd add site /name:$($servico.nomeSite) /"physicalPath:$diretorioInstalacao"
    Start-Sleep -Seconds $tempoSleep
    mu.validarComandoAnterior

    _echo "Removendo bindings $($servico.nomeSite)"
    & $appcmd set site /site.name:$($servico.nomeSite) /-bindings:"http/*:*:"
    Start-Sleep -Seconds $tempoSleep
    mu.validarComandoAnterior

    _echo "Configurando bindings $($servico.nomeSite)"
    & $appcmd set site /site.name:$($servico.nomeSite) /+"bindings.[protocol='http',bindingInformation='*:$($servico.porta):']"
    Start-Sleep -Seconds $tempoSleep
    mu.validarComandoAnterior

    _echo "Associando site ao pool $($servico.nomeSite)"
    & $appcmd set site /site.name:$($servico.nomeSite) /"[path='/'].applicationPool:$($servico.nomeSite)"
    Start-Sleep -Seconds $tempoSleep
    mu.validarComandoAnterior

    _echo "Realizando configuracoes adicionais no pool $($servico.nomeSite)"
    & $appcmd set apppool /apppool.name:$($servico.nomeSite) /enable32BitAppOnWin64:$($ativar32Bit) /startMode:AlwaysRunning /processModel.idleTimeout:00:00:00
    Start-Sleep -Seconds $tempoSleep
    mu.validarComandoAnterior

    _echo "Configurando identity pool"
    & $appcmd set apppool /apppool.name:$($servico.nomeSite) /processModel.identityType:SpecificUser
    & $appcmd set apppool /apppool.name:$($servico.nomeSite) /processModel.userName:$($configuracoes.acessos.usuarioAdministrador.usuario)
    $senhaDescriptografada = mu.descriptografarSenha $($configuracoes.acessos.usuarioAdministrador.senha)
    & $appcmd set apppool /apppool.name:$($servico.nomeSite) /processModel.password:$senhaDescriptografada

    if ("preloadEnabled" -in $servico.PSobject.Properties.Name -and $servico.preloadEnabled -eq $true) {
        & $appcmd set config -section:system.applicationHost/sites "/[name='$($servico.nomeSite)'].applicationDefaults.preloadEnabled:True" /commit:apphost
    }

    $siteAptoParaHttps = if (($nomeServico -eq "orcamentoWeb") -or ($nomeServico -eq "rest") -or ($nomeServico -eq "segurancaWeb") -or ($nomeServico -eq "imagensProdutos"))  {
        $true
    } else {
        $false
    }

    if ($siteAptoParaHttps -and ($($configuracoes.servicos."$nomeServico".configurarHttps) -eq $true)) {
        _mu.configurarSiteHttps $configuracoes $appcmd $nomeServico
    }
    

    _echo "Parando e iniciando pool e site $($servico.nomeSite)"

    & $appcmd stop apppool /apppool.name:$($servico.nomeSite)
    Start-Sleep -Seconds $tempoSleep
    mu.validarComandoAnterior

    & $appcmd start apppool /apppool.name:$($servico.nomeSite)
    Start-Sleep -Seconds $tempoSleep
    mu.validarComandoAnterior

    & $appcmd stop site /site.name:$($servico.nomeSite)
    Start-Sleep -Seconds $tempoSleep
    mu.validarComandoAnterior

    & $appcmd start site /site.name:$($servico.nomeSite)
    Start-Sleep -Seconds $tempoSleep
    mu.validarComandoAnterior

}

function global:_mu.configurarSiteHttps() {
    param(
        $configuracoes,
        $appcmd,
        #$certThumbprint,
        $nomeServico  
    )

    # if ($configuracoes.certificado.configurar -eq $false) {
    #     _echo "Configuracao de certificado digital desativada. Servico $($servico.nomeSite) nao sera configurado para HTTPS"
    #     return
    # }

    $servico = $configuracoes.servicos."$nomeServico"

    if (-not $servico.configurarHttps) {
        _echo "Configuracao HTTPS desativada para servico $($servico.nomeSite)"
        return
    }
    
    $tempoSleep = 2

    _echo "HTTPS para servico $($servico.nomeSite) sera configurado"
   
    $certThumbprint = (Get-ChildItem -Path Cert:LocalMachine\MY | Where-Object {$_.FriendlyName -eq $configuracoes.certificado.nome} | Select-Object Thumbprint).Thumbprint
    
    _echo "Assinatura digital do certificado $($configuracoes.certificado.nome): $certThumbprint"

    _echo "Removendo binding HTTPS para servico $($servico.nomeSite)"

    & $appcmd set site /site.name:$($servico.nomeSite) /-"bindings.[protocol='https',bindingInformation='*:$($servico.portaHttps):']"

    _echo "Adicionando binding HTTPS para servico $($servico.nomeSite)"
    

    & $appcmd set site /site.name:$($servico.nomeSite) /+"bindings.[protocol='https',bindingInformation='*:$($servico.portaHttps):']"

    netsh http delete sslcert ipport="0.0.0.0:$($servico.portaHttps)"

    #mu.validarComandoAnterior

    $guid = [guid]::NewGuid().ToString("B")

    netsh http add sslcert ipport="0.0.0.0:$($servico.portaHttps)" certhash="$certThumbprint" certstorename="MY" appid="$guid"

    if (($nomeServico -eq "orcamentoWeb") -or ($nomeServico -eq "rest")){
        _mu.configurarRedirecionamentoHttps $configuracoes $nomeServico
    }
    
}

function global:_mu.configurarRedirecionamentoHttps() {
    param(
        $configuracoes,
        $nomeServico
    )
    $servico = $configuracoes.servicos."$nomeServico"
    
    $ipHost = $configuracoes.enderecos.ipHost
    $porta = $servico.portaHttps

    $webConfig = "$($configuracoes.enderecos.diretorioBaseInstalacao)\$($servico.diretorioRelativoInstalacao)\Web.config"

    if (-not (test-path $webConfig)) {
        _echo "Arquivo web.config $webConfig nao encontrado" "warn"
        return
    }

    function removerTagsRewrite() {
        $xmlDoc = new-object -typename System.Xml.XmlDocument
        $xmlDoc.Load($webConfig)
    
        $tagsRewrite = $xmlDoc.GetElementsByTagName("rewrite")

        

        while ($tagsRewrite.Count -gt 0) {
            $tagRewrite = $tagsRewrite[0]
            
            $tagRewrite.ParentNode.RemoveChild($tagRewrite) | out-null

            $xmlDoc.Save($webConfig)

            $xmlDoc = new-object -typename System.Xml.XmlDocument
            $xmlDoc.Load($webConfig)

            $tagsRewrite = $xmlDoc.GetElementsByTagName("rewrite")
        }
    
    }

    _echo "Configurando redirecionamento automatico para $($servico.nomeSite)"

    (removerTagsRewrite)

    # return

    #foreach ($tagRewrite in $tagsRewrite) {
        #$tagRewrite.ParentNode.RemoveChild($tagRewrite) | out-null
    #}

    #$xmlDoc.Save($webConfig)

    #return

    
    _echo "Web.config: $webConfig"

    $xmlRewrite = "
        <rewrite>
            <rules>
            <rule name=""HTTPS force"" enabled=""true"" stopProcessing=""true"">
                <match url=""(.*)"" />
                <conditions>
                <add input=""{HTTPS}"" pattern=""^OFF$"" />
                </conditions>
                <action type=""Redirect"" url=""https://${ipHost}:${porta}"" redirectType=""Permanent"" />
            </rule>
            </rules>
        </rewrite>"

    $conteudoWebConfig = get-content $webConfig
    
    $linhaParaInserir = ((select-string -path $webConfig -pattern "</modules>")[0]).LineNumber - 1

    $conteudoWebConfig[$linhaParaInserir] += $xmlRewrite

    $conteudoWebConfig | set-content $webConfig -Encoding "utf8"

}



function global:mu.configurarSitesEPools() {
    param(
        $configuracoes,
        $diretorioReleaseWeb
    )

    $pstoolsPath = "$diretorioReleaseWeb\pstools"

    Set-Alias -Name psexec -Value "$(Join-Path -Path $pstoolsPath -ChildPath psexec)"
    $appcmd = "C:\\windows\\system32\\inetsrv\\appcmd.exe"

    _echo "Registrando tipos MIME estaticos no IIS"
    _mu.configurarTiposMime $appcmd

    TASKKILL /F /FI "IMAGENAME eq MicroUniverso.Venda.Orcamento.Host.Console.exe"
    
    # iisreset /stop
    # iisreset /start
    
    _mu.gerarCertificado $configuracoes

    _mu.configurarSite $configuracoes $appcmd "rest"
    _mu.configurarSite $configuracoes $appcmd "authServer"
    _mu.configurarSite $configuracoes $appcmd "resourceServer"
    _mu.configurarSite $configuracoes $appcmd "segurancaWeb"
    _mu.configurarSite $configuracoes $appcmd "imagensProdutos"
    _mu.configurarSite $configuracoes $appcmd "orcamentoWeb"
    _mu.configurarSite $configuracoes $appcmd "carrinhoDeCompra"
    _mu.configurarSite $configuracoes $appcmd "financeiro"
    _mu.configurarSite $configuracoes $appcmd "ordemDeCompra"
    _mu.configurarSite $configuracoes $appcmd "liberarPendencia"

    #$certThumbprint = _mu.gerarCertificadoAutoAssinado $configuracoes
    
    
    # _mu.configurarSiteHttps $configuracoes $appcmd "rest"
    # _mu.configurarSiteHttps $configuracoes $appcmd "segurancaWeb"
}
