##/*********************************************************************************************
##Author                :  Guravareddy.T
##Purpose               :  Display the Skype Video cals
##Created               :  11/08/2018
##Modified By		    :
##reference link        :(https://docs.microsoft.com/en-us/SkypeForBusiness/using-call-quality-in-your-organization/stream-classification-in-call-quality-dashboard)



clear
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$egInstallpath=Get-ChildItem Env:EGURKHA_INSTALL_DIR |Select Value
$egurkhaPath=$egInstallpath.Value.ToString()
$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
$egEncryPath=$scriptPath+"\EGFileEncryption.psm1"
$egDatnKy=$scriptPath+"\GetDatnKeyFiles.psm1"
Import-Module $egEncryPath,$egDatnKy

$testargs=$args
$reportingname='SBO\'+$testargs[0]
$longcaldurInMin=$testargs[1]
$egInstallpath=Get-ChildItem Env:EGURKHA_INSTALL_DIR |Select Value

    $readfiles=Eg-ReadFile -ComntRptPath $reportingname -FileName "SyVideoSessions" -keyFileName "kSyVideoSessions" -EgPath $egurkhaPath
    $datafile=$readfiles[1] -replace (".csv",".dat") 
    $csvfile=Unprotect-File $datafile -Algorithm AES -KeyAsPlainText $readfiles[0]
    [array]$userSession= import-csv $csvfile | Select-Object * | Where-Object { $_.MediaTypesDescription -Like "*Video*" } | Sort -property DialogId -Unique
                        			 			 					
    Remove-Item $csvfile
    Eg-DeleteFiles -FilePath $readfiles[2] -Pattern 'SyVideoSessions' -InputFile $readfiles[3]
    Eg-DeleteFiles -FilePath $readfiles[2] -Pattern 'kSyVideoSessions' -InputFile $readfiles[4]
    Write-Host "ReadFile:"$readfiles[3]


$totalvideocls=0
$cmptedVidCls=0
$poorcalscnt=0
$poorcalsperct=0
$failedcnt=0
$failedclsperct=0
$longcalscnt=0
$totalsesduration=0
$totalcnferncecals=0
$organisedcnfrnces=0
$CnfOrganisersCnt=0
$CnfParticpatedUsersCnt=0
$CurrentSessions=0
$totalbandwdthused=0
$longcalslist=@{}
$cnfurlStrtNendtime=@{}
$CnfrncurlNinstancid=@{} # confrence url as key and ConfInstance is value
$bandwithddmap=@{} # key as dd and value as bandwidth
$empty='-'
#Date Format 
$CultureDateTimeFormat = (Get-Culture).DateTimeFormat
$DateFormat = $CultureDateTimeFormat.ShortDatePattern
$TimeFormat = $CultureDateTimeFormat.LongTimePattern
$DateTimeFormat = "$DateFormat $TimeFormat"

if($longcaldurInMin -eq $null -and $longcaldurInMin -eq " "){ $longcaldurInMin=60 }
$longcaldurInMin=[int]$longcaldurInMin

if($userSession){
    $totalvideocls=$userSession.count
    ## getting the only conference sessions from all Appsharing sessions
    [array]$cnfrncecals=$userSession | Select-Object FromUri,ToUri,MediaTypesDescription,ConferenceUrl,ConfInstance,StartTime,EndTime | Where-Object { $_.MediaTypesDescription -Like "*Conference*"} 
    ## geeting current running sessions (endtime of session is null)
    [array]$currentcals=$userSession | Select-Object FromUri,ToUri,MediaTypesDescription,StartTime,EndTime | Where-Object { $_.EndTime -eq "" } | Sort-Object { $_.StartTime -as [datetime] } -Descending #| select -first 10 
    ## getting all audio sessions which are having the QoeReport
    [array]$output=$userSession | Select-Object * | Where-Object { $_.QoEReport -ne "" }
}

foreach($ot in $output)
{   
    $ot.QoeReport=($ot.QoeReport) | ConvertFrom-Json
    try{
        $poorcalboolen=$false
        $vidLcalfrmelossavg=""
        $vidpostPLR=""
        $vidfrmrate=""
        $BandwidthEst=0
        $fromIp=""
        $toIp=""
        # if( ($vidLcalfrmelossavg -gt 50 ) -or ($vidfrmrate -lt 7) -or ($vidpostPLR -gt 0.15))

        $videostremas=$ot.QoeReport.VideoStreams
        if ($videostremas -ne $null -and $videostremas -ne " ") {

            
            $vidLcalfrmelossavg=$ot.QoeReport.VideoStreams.VideoLocalFrameLossPercentageAvg
            if($vidLcalfrmelossavg -or $vidLcalfrmelossavg -eq 0){ if($vidLcalfrmelossavg -gt 50) {$poorcalboolen=$true } } else{$vidLcalfrmelossavg=""}
                     
            $vidfrmrate =$ot.QoeReport.VideoStreams.VideoFrameRateAvg
            if($vidfrmrate -or $vidfrmrate -eq 0){ if($vidfrmrate -lt 7) {$poorcalboolen=$true } } else{$vidfrmrate=""}

            $vidpostPLR =$ot.QoeReport.VideoStreams.VideoPostFECPLR
            if($vidpostPLR -or $vidpostPLR -eq 0){ if($vidpostPLR -gt 0.15) {$poorcalboolen=$true } } else{$vidpostPLR=""} 
             
            $Bandwidth=$ot.QoeReport.VideoStreams.BandwidthEst
            $bandwidthtotal=0;$count=0;$BandwidthEst=0
            foreach($bndwdt in $Bandwidth){if($bndwdt){$bandwidthtotal+=[long]$bndwdt;$count++ }}
            if($bandwidthtotal){$BandwidthEst=$bandwidthtotal/$count}    
      }

        [array]$medialLines=$ot.QoeReport.MediaLines
        if ($medialLines -ne $null -and $medialLines -ne " ") {
            $fromIp1="";$toIp1=""
            foreach($medllns in $medialLines)
            {
                  $fromIp1=($medllns.FromIPAddr).trim()
                  $toIp1=($medllns.ToIPAddr).trim()
                  if($fromIp1 -ne $toIp1)
                  {
                      $fromIp=$fromIp1;$toIp=$toIp1
                  }

            }
            if($fromIp -eq "" -or $toIp -eq "")
            {
                  $fromIp=$fromIp1;$toIp=$toIp1
            }
         }

    }catch{
        $errormsg=$_.Exception.Message 
        Write-Error "error while getting key video thresholds "$errormsg
    }

    $mediastrttime=Eg-ConvertTime -Time ([DateTime]($ot.QoeReport.Session.MediaStartTime).Replace('T',' '))
    $mediaendtime=Eg-ConvertTime -Time ([DateTime]($ot.QoeReport.Session.MediaEndTime).Replace('T',' '))
    $mediatype=($ot.MediaTypesDescription).Replace("]["," ").Replace("]","").Replace("[","")
    $MediaDurationInMinutes = ( $mediaendtime - $mediastrttime).TotalMinutes
    $totalsesduration=$totalsesduration+$MediaDurationInMinutes
    $fromdevice=$ot.QoeReport.medialines.FromRenderDev
    $todevice=$ot.QoeReport.medialines.ToRenderDev 

    $strindex =  if((($ot.ErrorReports)).IndexOf("UnexpectedFailure") -gt 0 -or (($ot.ErrorReports)).IndexOf("expectedFailure") -gt 0) { 10} else{0}
  
       if($strindex -gt 1)
       {
           $failedcnt++ 
           $ot.ErrorReports=($ot.ErrorReports).Replace('\','').Replace(';',',').Replace(':','=').Replace('"','').Replace('Reason','reason')
           $errorreport=""
           try{
                while($ot.ErrorReports.Length -gt 0)
                {
                    $frstobj=$ot.ErrorReports.Substring(0,$ot.ErrorReports.IndexOf('}')+1).trim()
                    $temp=$frstobj.Substring(1,$frstobj.IndexOf("reason")-1)
                    $frstobj=$frstobj.Substring($frstobj.IndexOf("reason"))
                    if($frstobj.Contains(',')){
                        $temp=$temp+$frstobj.Substring(0,$frstobj.IndexOf(","))+';'
                    }
                    else{
                        $temp=$temp+$frstobj.Substring(0,$frstobj.IndexOf("}"))+';'
                    }
                    if($temp.IndexOf("UnexpectedFailure") -gt 0 -or $temp.IndexOf("expectedFailure") -gt 0){
                        $errorreport=$errorreport+$temp
                        $temp=''
                    }
                    $ot.ErrorReports=$ot.ErrorReports.Substring($ot.ErrorReports.IndexOf('}')+1)
                }
             }catch{
                $excp=$_.Exception.Message
                Write-Error 'exception occures while getting error data ' $excp               
              }
          $faileddd=''+$mediastrttime+'~!~'+$mediaendtime+'~!~'+'-'+'~!~'+$mediatype+'~!~'+$ot.FromUri+'~!~'+$ot.FromClientVersion+'~!~'+'-'+'~!~'+'-'+'~!~'+'-'+'~!~'+$fromIp+'~!~'+$ot.FromTelNumber+'~!~'+ $ot.ToUri +'~!~'+$ot.ToClientVersion+'~!~'+'-'+'~!~'+'-'+'~!~'+'-'+'~!~'+$toIp+'~!~'+$ot.ToTelNumber+'~!~'+'-'+'~!~'+'-'+'~!~'+'-'+'~!~'+$errorreport
          write-host "#faildcaldd~" $faileddd
          $faileddd=''
       }


       if($poorcalboolen)
       {
           $poorcalscnt++ 
           $poorcalsdd= ''+$mediastrttime+'~!~'+$mediaendtime+'~!~'+$MediaDurationInMinutes+'~!~'+$mediatype+'~!~'+$ot.FromUri+'~!~'+$ot.FromClientVersion+'~!~'+$ot.QoeReport.Session.FromOS+'~!~'+$fromdevice+'~!~'+([array]$ot.QoeReport.medialines.FromNetworkConnectionDetail)[0]+'~!~'+'~!~'+$fromIp+'-'+'~!~'+$ot.ToUri+'~!~'+$ot.ToClientVersion+'~!~'+$ot.QoeReport.Session.ToOS+'~!~'+$todevice+'~!~'+([array]$ot.QoeReport.medialines.ToNetworkConnectionDetail)[0]+'~!~'+'~!~'+$toIp+'-'+'~!~'+$vidLcalfrmelossavg[0]+'~!~'+$vidfrmrate[0]+'~!~'+$vidpostPLR[0]
           Write-host '#poorcalsdd~' $poorcalsdd
           $poorcalsdd=''
       }

       if($MediaDurationInMinutes -gt $longcaldurInMin)
       {
          $longcalscnt++
          $longcalsdd=''+$mediastrttime+'~!~'+$mediaendtime+'~!~'+$MediaDurationInMinutes+'~!~'+$mediatype+'~!~'+$ot.FromUri+'~!~'+$ot.FromClientVersion+'~!~'+$ot.QoeReport.Session.FromOS+'~!~'+$fromdevice+'~!~'+([array]$ot.QoeReport.medialines.FromNetworkConnectionDetail)[0]+'~!~'+$fromIp+'~!~'+'-'+'~!~'+$ot.ToUri+'~!~'+$ot.ToClientVersion+'~!~'+$ot.QoeReport.Session.ToOS+'~!~'+$todevice+'~!~'+([array]$ot.QoeReport.medialines.ToNetworkConnectionDetail)[0]+'~!~'+$toIp
          $longcalslist.Add($longcalsdd,$mediaendtime)
          $longcalsdd=''
       }

       if($BandwidthEst){$BandwidthEst=[double]($BandwidthEst/(1024*1024*1024))}
       $totalbandwdthused=$totalbandwdthused+$BandwidthEst
       $BandwidthEst=$BandwidthEst.toString('#.####')
       $badwithdd=''+$mediastrttime+'~!~'+$mediaendtime+'~!~'+$empty+'~!~'+$mediatype+'~!~'+$ot.FromUri+'~!~'+$empty+'~!~'+$empty+'~!~'+$empty+'~!~'+$empty+'~!~'+$fromIp+'~!~'+$empty+'~!~'+$ot.ToUri+'~!~'+$empty+'~!~'+$empty+'~!~'+$empty+'~!~'+$empty+'~!~'+$toIp+'~!~'+$empty+'~!~'+$empty+'~!~'+$empty+'~!~'+$empty+'~!~'+$BandwidthEst
       $bandwithddmap.Add($badwithdd,$BandwidthEst)  
               
}

## sorting the long sessions depending the latest endtime 
foreach($longcaldd in $longcalslist.GetEnumerator() |  Sort-Object { $_.value -as [datetime] } -Descending)
{
    Write-host '#longcalsdd~' $longcaldd.key
}

foreach($bandwdtdd in $bandwithddmap.GetEnumerator() |  Sort-Object value  -Descending | select -First 10 )
{
    Write-host '#bandwidhtuseddd~' $bandwdtdd.key
}

## writting the top 10 current sessions by the latest start time
foreach($crtcal in $currentcals  | select -First 10)
{
    $CurrentSessions=$currentcals.Count
    $currentmediatype=($crtcal.MediaTypesDescription).Replace("]["," ").Replace("]","").Replace("[","")
    $crtcalStartTime = [DateTime]::ParseExact($crtcal.StartTime,$DateTimeFormat,[System.Globalization.DateTimeFormatInfo]::InvariantInfo,[System.Globalization.DateTimeStyles]::None)
    $dd=''+ (Eg-ConvertTime -Time ($crtcalStartTime))+'~!~'+$empty+'~!~'+$empty+'~!~'+$currentmediatype+'~!~'+$crtcal.FromURI+'~!~'+$empty+'~!~'+$empty+'~!~'+$empty+'~!~'+$empty+'~!~'+$empty+'~!~'+$empty+'~!~'+$crtcal.ToURI+'~!~'+$empty+'~!~'+$empty+'~!~'+$empty+'~!~'+$empty
    write-host '##currentcals' $dd
    $dd=$null
}


$CnfrurlNusers=@{}  # conferenceurl and users hashtable
$Cnfrurlusrcnt=@{}  # conferenceurl and users count hashtable
$cnfpartisipant=New-Object System.Collections.ArrayList #total conference paraticipated users list
$CnfOrgslist=New-Object System.Collections.ArrayList #unique conference organised users list
if($cnfrncecals)
{
    $totalcnferncecals=$cnfrncecals.count
    $cnfrncecals=$cnfrncecals | Select-Object * | Where-Object { $_.EndTime -ne ""}
    foreach($cfrccal in $cnfrncecals)
    {
        $cnfurl=$cfrccal.ConferenceUrl
        $instanceid=$cfrccal.ConfInstance
        $frmuri=$cfrccal.FromURI
        $touri= $cfrccal.ToURI
        $cfrccalStartTime = [DateTime]::ParseExact($cfrccal.StartTime,$DateTimeFormat,[System.Globalization.DateTimeFormatInfo]::InvariantInfo,[System.Globalization.DateTimeStyles]::None)
        $cfrccalEndTime = [DateTime]::ParseExact($cfrccal.EndTime,$DateTimeFormat,[System.Globalization.DateTimeFormatInfo]::InvariantInfo,[System.Globalization.DateTimeStyles]::None)
        $strtime=Eg-ConvertTime -Time $cfrccalStartTime
        $endtme=Eg-ConvertTime -Time $cfrccalEndTime

        if($CnfrurlNusers.Contains($cnfurl))
        {
            $list=$CnfrurlNusers[$cnfurl]
            if(!$list.Contains($FromURI)) { $null=$list.Add($frmuri) }

            if(!$list.Contains($touri)) { $null=$list.Add($touri) }

            if(!$cnfpartisipant.Contains($FromURI)) { $null=$cnfpartisipant.Add($frmuri)}
            if(!$cnfpartisipant.Contains($touri)) { $null=$cnfpartisipant.Add($touri)}

        }
        else
        {
            $list=New-Object System.Collections.ArrayList
            $list.Add($frmuri)
            if(!$list.Contains($touri))
            {
              $null=$list.Add($touri)  
            }
            $null=$CnfrurlNusers.Add($cnfurl,$list)
            if(!$cnfpartisipant.Contains($FromURI)) { $null=$cnfpartisipant.Add($frmuri)}
            if(!$cnfpartisipant.Contains($touri)) { $null=$cnfpartisipant.Add($touri)}
            $null=$CnfrncurlNinstancid.Add($cnfurl,$instanceid)   #adding cnfurl and instnce id to map
        }

        ### getting the start time and end time of the each conference

        if($cnfurlStrtNendtime.Contains($cnfurl))
        {
            $strttime1=$cnfurlStrtNendtime[$cnfurl]['starttime']
            if(([datetime]$strtime) -lt ([datetime]$strttime1)){$cnfurlStrtNendtime[$cnfurl]['starttime']=$strtime}
            $endtime1=$cnfurlStrtNendtime[$cnfurl]['endtime']
            if(([datetime]$endtme) -gt ([datetime]$endtime1)){$cnfurlStrtNendtime[$cnfurl]['endtime']=$endtme}
        }
        else
        {
            $temp=@{}
            $temp.Add('starttime',$strtime)
            $temp.Add('endtime',$endtme)
            $cnfurlStrtNendtime.Add($cnfurl,$temp)
        }

    }
}

if($CnfrurlNusers)
{
   $totalcnferncecals=$CnfrurlNusers.count

    foreach($parcon in $CnfrurlNusers.GetEnumerator())
    {
        $cnfurl=($parcon.key).ToString()
        $CnfOrgUser=$cnfurl.Substring(4,$cnfurl.IndexOf(";"))
        $CnfOrgUser=$CnfOrgUser.Substring(0,$CnfOrgUser.IndexOf(";"))
        if(!$CnfOrgslist.Contains($CnfOrgUser)) { $null=$CnfOrgslist.Add($CnfOrgUser)}
        $cnt=$parcon.value.count
        $null=$Cnfrurlusrcnt.Add($parcon.key,$cnt)
	}

    foreach($entry in $Cnfrurlusrcnt.GetEnumerator() | sort -Property value -Descending | select -First 10)
    {
    $cnfurl=($entry.key).ToString()
    $CnfOrgUser=$cnfurl.Substring(4,$cnfurl.IndexOf(";"))
    $CnfOrgUser=$CnfOrgUser.Substring(0,$CnfOrgUser.IndexOf(";"))
    if($CnfrurlNusers[$cnfurl].Count -gt 5){$CnfrurlNusers[$cnfurl].Remove($CnfOrgUser)}
    $CnfPartUsrs=([String]($CnfrurlNusers[$cnfurl] | select -First 5)).Replace(" ",",")
     Write-Host  '##conferencedd~' $CnfrncurlNinstancid[$entry.key]  '~!~' $CnfOrgUser '~!~' $entry.value '~!~' $CnfPartUsrs ~!~ $cnfurlStrtNendtime[$cnfurl]['starttime'] '~!~' $cnfurlStrtNendtime[$cnfurl]['endtime']
	}
}

    $cmptedVidCls=$totalvideocls-$CurrentSessions
    if($cmptedVidCls -gt 0 -and $poorcalscnt -gt 0)
    {
        $poorcalsperct=((($poorcalscnt/$cmptedVidCls))*100).tostring("#.##")
    }
    if($cmptedVidCls -gt 0 -and $failedcnt -gt 0)
    {
        $failedclsperct=((($failedcnt/$cmptedVidCls))*100).tostring("#.##")
    }

    if($CnfOrgslist) { $CnfOrganisersCnt=$CnfOrgslist.count }
    if($cnfpartisipant) { $CnfParticpatedUsersCnt=$cnfpartisipant.count }
    if($totalsesduration) {$totalsesduration=[double]$totalsesduration.ToString('#.##')}
    if($totalbandwdthused){$totalbandwdthused=[double]$totalbandwdthused.ToString('#.####')}
    Write-Host 'measures~' $cmptedVidCls ~ $CurrentSessions ~ $poorcalscnt ~ $poorcalsperct ~ $failedcnt ~ $failedclsperct ~ $longcalscnt ~ $totalsesduration ~ $totalcnferncecals ~ $CnfOrganisersCnt ~ $CnfParticpatedUsersCnt ~ $totalbandwdthused