# 主脚本参数
param (
    [string]$Action, 
    [string]$Version
)
. .\comm.ps1 

$Appcmd = Join-Path $env:windir "system32\inetsrv\appcmd.exe"
# 安装函数
function Install {
    param (
        [string]$Version
    )
    Lang-Print -Msg "如果此进度超过10分钟，您可能需要进入服务器手动安装IIS（手动安装后需要通过面板再安装一次）或者重启下服务器后重新安装" -Arguments @("")
    # 执行 pkgmgr 命令安装 IIS 组件
    Lang-Print -Msg "正在安装 IIS 组件，请稍候..." -Arguments @("")
    Start-Process -FilePath "cmd.exe" -ArgumentList "/c start /w pkgmgr /iu:IIS-WebServerRole;IIS-WebServer;IIS-CommonHttpFeatures;IIS-StaticContent;IIS-DefaultDocument;IIS-DirectoryBrowsing;IIS-HttpErrors;IIS-HttpRedirect;IIS-ApplicationDevelopment;IIS-ASP;IIS-CGI;IIS-ISAPIExtensions;IIS-ISAPIFilter;IIS-ServerSideIncludes;IIS-HealthAndDiagnostics;IIS-HttpLogging;IIS-LoggingLibraries;IIS-RequestMonitor;IIS-HttpTracing;IIS-CustomLogging;IIS-ODBCLogging;IIS-Security;IIS-BasicAuthentication;IIS-WindowsAuthentication;IIS-DigestAuthentication;IIS-ClientCertificateMappingAuthentication;IIS-IISCertificateMappingAuthentication;IIS-URLAuthorization;IIS-RequestFiltering;IIS-IPSecurity;IIS-Performance;IIS-HttpCompressionStatic;IIS-HttpCompressionDynamic;IIS-WebServerManagementTools;IIS-ManagementScriptingTools;IIS-ASPNET;IIS-NetFxExtensibility;IIS-ManagementService;IIS-ManagementConsole;IIS-IIS6ManagementCompatibility; /norestart" -Wait -NoNewWindow


    #检测w3svc服务是否安装成功
    $service = Get-Service -Name W3SVC -ErrorAction SilentlyContinue
    if ($null -eq $service) {
        Lang-Print -Msg "无法自动安装IIS,请手动安装IIS后重新执行安装IIS任务" -Arguments @()
        exit 1
    }

    Set-Service -Name W3SVC -StartupType Automatic

    Start-Service -Name W3SVC -ErrorAction Stop

    # 修改 HTTP 服务启动类型
    try {
        Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\HTTP" -Name "Start" -Value 3 -Type DWord
    } catch {
        Lang-Print -Msg "无法修改 HTTP 服务启动类型: {}" -Arguments @($_)
    }

    #判断服务状态
    $service = Get-Service -Name w3svc -ErrorAction SilentlyContinue
    if ($null -eq $service) {
        Lang-Print -Msg "IIS 服务未安装或未正确安装" -Arguments @()
        exit 1
    }
    if ($service.Status -ne 'Running') {
        Lang-Print -Msg "正在启动:{}" -Arguments @("IIS")
        Start-Service -Name w3svc
    } else {
        Lang-Print -Msg "IIS 服务已在运行" -Arguments @()
    }

    # 创建目录
    $log_dir = Join-Path $SOFT_PATH "wwwlogs"
    if (-not (Test-Path $log_dir)) {
        New-Item -Path $log_dir -ItemType Directory | Out-Null
    }
    Lang-Print -Msg "正在设置日志目录:{}" -Arguments @($log_dir)
    Invoke-AppCmd -Command "set config -section:system.applicationHost/sites /siteDefaults.logFile.directory:$log_dir /commit:apphost"

    Lang-Print -Msg "正在启用Asp" -Arguments @("")
    Invoke-AppCmd -Command "set config /section:asp /enableParentPaths:True /commit:apphost"
    Invoke-AppCmd -Command "set config -section:anonymousAuthentication /userName:`"`" /commit:apphost"

    Lang-Print -Msg "正在启用.Net3.5(2-3分钟)" -Arguments @("")
    Invoke-Cmd-NoOut -Command "DISM /Online /Enable-Feature /FeatureName:NetFx3 /NoRestart"
    Invoke-Cmd-NoOut -Command "DISM /Online /Enable-Feature /all /FeatureName:NetFx3 /NoRestart"

    Invoke-Cmd-NoOut -Command "DISM /online /enable-feature /all /featurename:IIS-ASPNET45 /NoRestart"

    Lang-Print -Msg "正在优化iis默认页" -Arguments @("")
    $default_list = @('default.html', 'default.asp', 'default.aspx', 'index.php', 'index.asp', 'index.aspx')
    foreach ($key in $default_list) {
       Invoke-AppCmd-NoOut -Command "set config /section:defaultDocument /+files.[value='$key']"
    }

    try {
        $iisRegPath = "HKLM:\SOFTWARE\Microsoft\InetStp"
        $iisVersion = (Get-ItemProperty -Path $iisRegPath -Name "MajorVersion").MajorVersion
        if ($iisVersion -gt 9) {
            Set-ItemProperty -Path $iisRegPath -Name "MajorVersion" -Value 9
        }
    } catch {
        Lang-Print -Msg "无法访问或修改注册表: {}" -Arguments @($_)
    }

    #iis.setup
    $conf_file = Join-Path $ROOT_PATH "data/iis.setup"
    if (-not (Test-Path $conf_file)) {
        New-Item -Path $conf_file -ItemType File | Out-Null
    }

    Set-URLRewrite
    Set-Proxy
    Set-Php

    Configure-IIS

    Write-Host "Successfully"
}



function Configure-IIS {

    Lang-Print -Msg "正在配置 IIS" -Arguments @("")
    Invoke-AppCmd -Command "unlock config -section:system.webServer/handlers"

    Lang-Print -Msg "正在注销组件" -Arguments @("")
    regsvr32 /u /s "$env:windir\system32\wshom.ocx"
    regsvr32 /u /s "$env:windir\system32\shell32.dll"


    Lang-Print -Msg "正在优化 IIS" -Arguments @("")
    Invoke-AppCmd -Command "set config /section:system.webServer/serverRuntime /appConcurrentRequestLimit:100000"

    try {
        Lang-Print -Msg "正在修改注册表以优化 HTTP 参数" -Arguments @("")
        Set-ItemProperty -Path "HKLM:\System\CurrentControlSet\Services\HTTP\Parameters" -Name "MaxConnections" -Value 100000 -Type DWord
        Set-ItemProperty -Path "HKLM:\System\CurrentControlSet\Services\HTTP\Parameters" -Name "MaxFieldLength" -Value 32768 -Type DWord
        Set-ItemProperty -Path "HKLM:\System\CurrentControlSet\Services\HTTP\Parameters" -Name "MaxRequestBytes" -Value 32768 -Type DWord
    } catch {
        Lang-Print -Msg "修改注册表失败: {}" -Arguments @($_)
    }
    # 配置 Windows 身份验证
    Invoke-AppCmd-NoOut -Command "set config -section:system.webServer/security/authentication/windowsAuthentication /enabled:true"
    
    # 配置静态内容
    Lang-Print -Msg "正在配置静态内容" -Arguments @("")
    Invoke-AppCmd-NoOut -Command "set config /section:staticContent /+[fileExtension='.',mimeType='text/plain']"

    #配置静态缓存 jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf|svg
    Lang-Print -Msg "正在配置静态缓存" -Arguments @("")
    $ext_list = @('.jpg', '.png', '.gif', '.css', '.js', '.woff', '.woff2', '.ttf', '.svg')
    foreach ($ext in $ext_list) {
        Invoke-AppCmd-NoOut -Command "set config /section:system.webServer/caching /+profiles.[extension='$ext',policy='CacheForTimePeriod',kernelCachePolicy='CacheForTimePeriod',duration='30.00:00:00']"
    }
    Lang-Print -Msg "正在启用.Net4.5支持" -Arguments @("")
    Invoke-Cmd-NoOut -Command "DISM /online /enable-feature /featurename:IIS-ASPNET45 /NoRestart"
    Invoke-Cmd-NoOut -Command "DISM /online /enable-feature /all /featurename:IIS-ASPNET45 /NoRestart"


    # #注册所有的.net到iis
    # $net_versions = @(    
    #     "$env:windir\Microsoft.NET\Framework\v4.0.30319",      
    #     "$env:windir\Microsoft.NET\Framework64\v4.0.30319"
    # )
    # foreach ($net_path in $net_versions) {
    #     if (Test-Path $net_path) {
    #         $exe = Join-Path $net_path "aspnet_regiis.exe"
    #         if (Test-Path $exe) {
    #             Lang-Print -Msg "正在注册 $exe 到 IIS" -Arguments @("")
    #             Start-Process -FilePath $exe -ArgumentList "-i" -Wait -NoNewWindow
    #         }
    #     }
    # }

    # 重启 IIS
    Lang-Print -Msg "正在重启 IIS" -Arguments @("")
    iisreset /start
}

#伪静态扩展
function Set-URLRewrite {

    #检测是否安装URL Rewrite
    $appcmd = "$env:windir\system32\inetsrv\appcmd.exe"
    # $result = & $appcmd list modules | Select-String "RewriteModule"
    # if ($result) {
    #     Lang-Print -Msg "URLRewrite 已安装" -Arguments @("")
    #     return
    # } 

    $Url =  "$DownNode/win/URLRewrite_x64.msi"  
    $localPath =  "$SOFT_PATH/temp/URLRewrite.msi"  
    Lang-Print -Msg "正在安装 URLRewrite" -Arguments @("")

    if (-not (Download-File -Url $Url -OutputPath $localPath)) {
        Lang-Print -Msg "下载 URLRewrite 失败" -Arguments @("")
        return
    }

    Lang-Print -Msg "正在安装 URLRewrite" -Arguments @("")
    Lang-Print -Msg "如果此进度超过1分钟,则需要重启服务器完成安装" -Arguments @("")

    #Start-Process -FilePath "msiexec.exe" -ArgumentList "/i `"$localPath`" /qn /norestart" -Wait -NoNewWindow
    Invoke-Cmd -Command "$localPath /qb"
}

#反向代理扩展
function Set-Proxy{
    #检测是否安装RequestRouter
    $log_file = "$ROOT_PATH/data/iis_requestRouter.log"
    if (Test-Path $log_file) {
        Remove-Item $log_file -Force       
    }
    Invoke-AppCmd -Command "list config /section:proxy > $log_file 2>&1"

    # $bodyStr = Get-Content $log_file -Raw
    # $result = $bodyStr | Select-String "httpVersion"
    # if ($result) {
    #     Lang-Print -Msg "RequestRouter 已安装" -Arguments @("")
    #     return
    # }

    $Url = "$DownNode/win/panel/data/requestRouter_x64.msi"  # 替换为实际的下载地址
    $localPath =  "$SOFT_PATH/temp/requestRouter.msi"       # 下载到临时目录

    Lang-Print -Msg "正在安装 RequestRouter" -Arguments @("")
    if (-not (Download-File -Url $Url -OutputPath $localPath)) {
        Lang-Print -Msg "下载 RequestRouter 失败" -Arguments @("")
        return
    }


    #Start-Process -FilePath "msiexec.exe" -ArgumentList "/i `"$localPath`" /qn /norestart" -Wait -NoNewWindow
    Invoke-Cmd -Command "$localPath /qb"

    Invoke-AppCmd "set config /section:proxy /enabled:true /httpVersion:PassThrough /keepAlive:true /timeout:0.00:02:00 /reverseRewriteHostInResponseHeaders:true /xForwardedByHeader:X-Forwarded-Host /xForwardedForHeaderName:X-Forwarded-For /includePortInXForwardedFor:true /minResponseBuffer:256 /maxResponseHeaderSize:65536 /proxy: /proxyBypass: /cache.enabled:true /cache.validationInterval:0.00:01:00 /commit:apphost"
}

# iis追加PHP扩展
function Set-Php{
    
    #判断w3svc服务是否安装
    if (-not (Get-Service -Name w3svc -ErrorAction SilentlyContinue)) {      
        return
    }
  
    # 定义循环次数
    for ($x = 0; $x -le 15; $x++) {
        Invoke-AppCmd-NoOut "set config /section:system.webServer/fastCGI /-[InstanceMaxRequests='10000']"
        Invoke-AppCmd-NoOut "set config /section:system.webServer/handlers /-[path='*.php']"
    }
    # 定义 PHP 安装路径
    $php_dir_path = Join-Path $SOFT_PATH "php"

    # 遍历 PHP 目录
    $phpDirs = Get-ChildItem -Path $php_dir_path -Directory
    foreach ($dir in $phpDirs) {
        $PhpCgiPath = Join-Path $dir.FullName "php-cgi.exe"
        $PhpIniPath = Join-Path $dir.FullName "php.ini"

        if (Test-Path $PhpCgiPath) {
            $phpVersion = $dir.Name
            Lang-Print -Msg "正在安装 PHP-{} 扩展" -Arguments @($phpVersion)

            Invoke-AppCmd "set config /section:system.webServer/fastCGI /+[fullPath='$PhpCgiPath']"
            Invoke-AppCmd-NoOut "set config /section:system.webServer/handlers /+[name='PHP_FastCGI',path='*.php',verb='*',modules='FastCgiModule',scriptProcessor='$PhpCgiPath',resourceType='File']"
            Invoke-AppCmd-NoOut "set config -section:system.webServer/defaultDocument /+`"files.[value='index.php']`" /commit:apphost"
            Invoke-AppCmd "set config -section:system.webServer/fastCGI /[fullPath='$PhpCgiPath'].instanceMaxRequests:10000"
            Invoke-AppCmd "set config -section:system.webServer/fastCgi /[fullPath='$PhpCgiPath',arguments=''].activityTimeout:`"90`" /commit:apphost"
            Invoke-AppCmd "set config -section:system.webServer/fastCgi /[fullPath='$PhpCgiPath',arguments=''].requestTimeout:`"90`" /commit:apphost"
            Invoke-AppCmd "set config -section:system.webServer/fastCgi /[fullPath='$PhpCgiPath'].monitorChangesTo:`"$PhpIniPath`""
            Invoke-AppCmd "set config -section:system.webServer/fastCgi /+`"[fullPath='$PhpCgiPath'].environmentVariables.[name='PHP_FCGI_MAX_REQUESTS',value='10000']`""
        }
    }
}

# 卸载函数
function UnInstall {

    Lang-Print -Msg "正在卸载:{}" -Arguments @("IIS")

    sc stop w3svc
    Set-Service -Name w3svc -StartupType Disabled

    $conf_file = "$ROOT_PATH/data/iis.setup"
    if (Test-Path $conf_file) {
        Remove-Item $conf_file -Force       
    } 
    Lang-Print -Msg "卸载完成:{}" -Arguments @("IIS")
}

function Invoke-AppCmd {
    param([string]$Command)
    Start-Process -FilePath "cmd.exe" -ArgumentList "/c $Appcmd $Command" -Wait -NoNewWindow
}

function Invoke-AppCmd-NoOut {
    param([string]$Command)
  
    cmd /c "$Appcmd $Command" > $null 2>&1
}

switch ($Action.ToLower()) {
    "install" {       
        Install -Version $Version
    }
    "uninstall" {
        UnInstall
    }    
}
