class AppServiceHostName {
    [string] $resourceId = ""
    [string] $subscriptionId = ""
    [string] $subscriptionName = ""
    [string] $webAppName = ""
    [string] $resourceGroupName = ""
    [string] $slotName = ""
    [string] $hostname  = ""
}

function Effectory-GetAppServiceHostNames () {
    $subscriptions = Get-AzSubscription
    [AppServiceHostName[]]$ResultGetAppServiceHostNames = @()

    foreach ($subscription in $subscriptions) 
    {
        $subscriptionContext = Set-AzContext -SubscriptionId $subscription.Id
        $allWebApps = Get-AzWebApp

        foreach ($webApp in $allWebApps) {
            foreach ($webappHostName in $webApp.HostNames) {
                [AppServiceHostName] $appServiceHostName = [AppServiceHostName]::new()
                $appServiceHostName.resourceId = $webApp.Id
                $appServiceHostName.subscriptionId = $subscription.Id
                $appServiceHostName.subscriptionName = $subscription.Name
                $appServiceHostName.webAppName = $webApp.Name
                $appServiceHostName.resourceGroupName = $webApp.ResourceGroup
                $appServiceHostName.slotName = ""
                $appServiceHostName.hostname = $webappHostName
                $ResultGetAppServiceHostNames += $appServiceHostName
            }

            $webAppSlots = Get-AzWebAppSlot -Name $webApp.Name -ResourceGroupName $webApp.ResourceGroup
            foreach ($webAppSlot in $webAppSlots) {
                foreach ($webappSlotHostName in $webAppSlot.HostNames) {
                    [AppServiceHostName] $appServiceHostNameSlot = [AppServiceHostName]::new()
                    $appServiceHostNameSlot.resourceId = $webApp.Id
                    $appServiceHostNameSlot.subscriptionId = $subscription.Id
                    $appServiceHostNameSlot.subscriptionName = $subscription.Name
                    $appServiceHostNameSlot.webAppName = $webApp.Name
                    $appServiceHostNameSlot.resourceGroupName = $webApp.ResourceGroup
                    $appServiceHostNameSlot.slotName = $webappSlot.Name
                    $appServiceHostNameSlot.hostname = $webappSlotHostName
                    $ResultGetAppServiceHostNames += $appServiceHostNameSlot
                }
            }
        }
    }

    return $ResultGetAppServiceHostNames
}

class FrontDoorHostName {
    [string] $resourceId = ""
    [string] $subscriptionId = ""
    [string] $subscriptionName = ""
    [string] $frontDoorName = ""
    [string] $endPointName = ""
    [string] $hostname  = ""
}

function Effectory-GetFrontDoorHostNames () {
    $subscriptions = Get-AzSubscription
    [FrontDoorHostName[]]$ResultGetFrontDoorHostNames = @()

    foreach ($subscription in $subscriptions) 
    {
        $subscriptionContext = Set-AzContext -SubscriptionId $subscription.Id
        $allFrontDoors = Get-AzFrontDoor

        foreach ($frontDoor in $allFrontDoors) {

            foreach ($frontDoorEndPoint in $frontDoor.FrontendEndpoints) {
                [FrontDoorHostName] $frontDoorHostName = [FrontDoorHostName]::new()
                $frontDoorHostName.resourceId = $frontDoor.Id
                $frontDoorHostName.subscriptionId = $subscription.Id
                $frontDoorHostName.subscriptionName = $subscription.Name
                $frontDoorHostName.frontDoorName = $frontDoor.Name
                $frontDoorHostName.endPointName = $frontDoorEndPoint.Name
                $frontDoorHostName.hostname = $frontDoorEndPoint.HostName
                $ResultGetFrontDoorHostNames += $frontDoorHostName
            }
        }
    }

    return $ResultGetFrontDoorHostNames
}


class HostCheck {
    [string] $HostName = ""
    [string] $Fqdn = ""
    [string] $CName = ""
    [string] $IpAddress = ""
    [bool] $Exists = $false
    [bool] $RegisteredInExternalDNS = $false;
}

function HostExistsInExternal ([HostCheck] $hostCheck, [string] $ExternalDNSServer) {
    try {
        $CnameChain = resolve-dnsname -name $hostCheck.Fqdn -DnsOnly -Type A -NoHostsFile -Server $ExternalDNSServer -ErrorAction Ignore

        foreach ($chainItem in $CnameChain) {
            if ($chainItem.NameHost -ieq $hostCheck.CName) {
                $hostCheck.RegisteredInExternalDNS = $true
                return $hostCheck
            }
        }
    }
    catch {
        $hostCheck.RegisteredInExternalDNS = $false
    }

    $hostCheck.RegisteredInExternalDNS = $false
    return $hostCheck
}

function GetIPAddress ([HostCheck] $hostCheck) {
    try {
        $hostAddresses = [System.Net.Dns]::GetHostAddresses($hostCheck.Fqdn)
        $hostCheck.IpAddress = $hostAddresses.IPAddressToString
        
    }
    catch { 
        try {
            $hostAddresses = [System.Net.Dns]::GetHostAddresses($hostCheck.HostName)

            $hostCheck.IpAddress = $hostAddresses.IPAddressToString
        }
        catch {
            $hostCheck.IpAddress = ""
        }

    }
    return $hostCheck
}

function TestIPConnection ([HostCheck] $hostCheck) {
    try {
        if (Test-Connection -TargetName $hostCheck.IpAddress -Count 1 -Quiet) {
            $hostCheck.Exists = $true
        }
        else {
            $hostCheck.Exists = $false
        }
    }
    catch {
        $hostCheck.Exists = $false
    }
    return $hostCheck
}

function Effectory-DNSVerify (
    [string] $ZoneName = "effectory.com", 
    [string] $DNSServer = "DC1.effectory.local",
    [string] $ExternalDNSServer = "8.8.8.8",
    [string] $Type = "CName",
    [boolean] $DoIpCheck = $false) {
    
    Clear-DnsClientCache

    $DNSRecords = Get-DnsServerResourceRecord -ZoneName $ZoneName -computername $DNSServer -RRType $Type

    # HostName                  RecordType Type       Timestamp            TimeToLive      RecordData
    # --------                  ---------- ----       ---------            ----------      ----------
    # accept                    CNAME      5          0                    01:00:00        effectorycorporate2-accept.azurewebsites.net.
    # accept-authorization      CNAME      5          0                    01:00:00        authorization-web-api-accept.azurewebsites.net.
    # accept-beta-project       CNAME      5          0                    01:00:00        webclient-project-accept.azurewebsites.net.
    # accept-cluster            CNAME      5          0                    01:00:00        test-cluster-effectory-accept.azurewebsites.net.
    # accept-customer           CNAME      5          0                    01:00:00        test-customer-effectory-accept.azurewebsites.net.
    # accept-dashboard          CNAME      5          0                    01:00:00        dashboard-effectory-accept.azurewebsites.net.

    [HostCheck[]]$Result = @()

    foreach ($DNSRecord in $DNSRecords) {

        [HostCheck] $hostCheck = [HostCheck]::new()
        $hostCheck.HostName = $DNSRecord.HostName
        
        [string] $fqdn = $DNSRecord.HostName
        if (-not ($fqdn.ToLowerInvariant().EndsWith($ZoneName.ToLowerInvariant()))) {
            $fqdn = "$($DNSRecord.HostName).$($ZoneName)"
        }
        $hostCheck.Fqdn = $fqdn

        [string] $cname = $DNSRecord.RecordData.HostNameAlias
        if ($cname.EndsWith(".")) {
            $cname = $cname.Remove($cname.Length - 1, 1)
        }
        $hostCheck.CName = $cname

        $hostCheck = HostExistsInExternal -hostCheck $hostCheck -ExternalDNSServer $ExternalDNSServer
        $hostCheck = GetIPAddress -hostCheck $hostCheck
        if ($DoIpCheck) {
            $hostCheck = TestIPConnection -hostCheck $hostCheck
        } else {
            $hostCheck.Exists = $hostCheck.IpAddress -ne ""
        }

        $Result += $hostCheck
    }

    return $Result
}

function Effectory-DNSVerify-Csv (
    [string[]] $FileName, 
    [string] $ExternalDNSServer = "8.8.8.8") {
    
    Clear-DnsClientCache
    
    $DNSRecords = import-csv $FileName -Header 'HostName', 'Cname', 'Fqdn'

    # HostName,Cname,Fqdn
    # accept-authorization,authorization-web-api-accept.azurewebsites.net,accept-authorization.effectory.com
    # accept-customer,test-customer-effectory-accept.azurewebsites.net,accept-customer.effectory.com
    # accept-ecestore,test-ecestore-accept.azurewebsites.net,accept-ecestore.effectory.com

    [HostCheck[]]$Result = @()
    foreach ($DNSRecord in $DNSRecords) {

        [HostCheck] $hostCheck = [HostCheck]::new()
        $hostCheck.HostName = $DNSRecord.HostName
        $hostCheck.CName = $DNSRecord.Cname
        $hostCheck.Fqdn = $DNSRecord.Fqdn

        $hostCheck = HostExistsInExternal -hostCheck $hostCheck -ExternalDNSServer $ExternalDNSServer
        $hostCheck = GetIPAddress -hostCheck $hostCheck
        $hostCheck.Exists = $hostCheck.IpAddress -ne ""

        $Result += $hostCheck
    }
    
    return $Result
}

function Effectory-DNSClean-Csv (
    [string[]] $FileName, 
    [string] $DNSServer = "DC1.effectory.local",
    [string] $Type = "CNAME") {
    
    Clear-DnsClientCache
    
    $DNSRecords = import-csv $FileName -Header 'HostName', 'ZoneName'

    # HostName,ZoneName
    # accountmanagertools,effectory.local
    # alex,effectory.local
    # webstage.beste-werkgevers,effectory.local

    foreach ($DNSRecord in $DNSRecords) {
        
        if (($DNSRecord.HostName -eq "HostName")) {
            continue;
        }

        Write-Host "Deleting $($DNSRecord.HostName) from $($DNSRecord.ZoneName)"

        try {
            Remove-DnsServerResourceRecord -ComputerName $DNSServer -ZoneName $DNSRecord.ZoneName -RRType $Type -Name $DNSRecord.HostName -Force 
        }
        catch { }
    }
}

#Connect-AzAccount

#Effectory-DNSVerify -ZoneName "effectory.com" -DNSServer "DC1.effectory.local" -ExternalDNSServer "8.8.8.8" | Export-Csv -Path ".\2021-06-01 DNS-effectory-com.csv"
#Effectory-DNSVerify -ZoneName "effectory.local" -DNSServer "DC1.effectory.local" -ExternalDNSServer "DC2.effectory.local" -DoIpCheck $true | Export-Csv -Path ".\2021-06-01 DNS-effectory-local.csv" 
#Effectory-DNSVerify-Csv -FileName .\vip-effectory-com.csv -ExternalDNSServer "8.8.8.8" | Export-Csv -Path ".\2021-06-01 DNS-vip-effectory-com.csv"
#Effectory-GetAppServiceHostNames | Export-Csv -Path ".\2021-06-01 AppService Hosts.csv"
Effectory-GetFrontDoorHostNames | Export-Csv -Path ".\2021-06-01 FrontDoor Hosts.csv"

# | Format-Table
# | Export-Csv -Path .\DNS-xxxx.csv

#Effectory-DNSClean-Csv -FileName .\deletedns.csv -DNSServer "DC1.effectory.local"