import os 
import sys 

ps_content=r'''
<#  
    .Name
    EZT-AudioPlayer
    
    .Version 
    0.2

    .SYNOPSIS
    Plays specified phrases with TTS and/or plays audio files from a specified folder/file path

    .DESCRIPTION
       
    .Configurable Variables:

    .EXAMPLE
    \EZT-AudioPlayer.ps1

    .OUTPUTS
    System.Management.Automation.PSObject

    .Credits

    .NOTES
    Author: EZTechhelp
#>

#---------------------------------------------- 
#region Config Variables
#----------------------------------------------
$text_to_Speak = "''' + itsm.getParameter('Text_to_Speak') + '''" #Pharse that should be spoken by TTS
$text_to_Speech_Speed = "''' + itsm.getParameter('Text_to_Speech_Speed') + '''" #Speed of TTS. -10 is slowest, 10 is fastest, 0 is default/normal
$Play_Audio_Path = "''' + itsm.getParameter('Play_Audio_Path') + '''" #Full path to a single audio file or folder containing audio files
$Play_Audio_Filter = "''' + itsm.getParameter('Play_Audio_Filter') + '''" #specify the audio file names, formats or other filters that are allowed to be played, comma seperated. Supported format depends on what is supported by Windows Media Player
$Shuffle = "''' + itsm.getParameter('Shuffle') + '''" # 1 = Enable Random Shuffle when playing multiple audio files, 0 (or anything else) = Disable
#---------------------------------------------- 
#endregion Config Variables
#----------------------------------------------

#---------------------------------------------- 
#region Show-NotifyBallon Function
#----------------------------------------------
Function Show-NotifyBalloon($Message)
{
  [system.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms') | Out-Null            
  $Global:Balloon = New-Object System.Windows.Forms.NotifyIcon            
  $Balloon.Icon =  [System.Drawing.Icon]::ExtractAssociatedIcon((Get-Process -id $pid | Select-Object -ExpandProperty Path))                    
  $Balloon.BalloonTipIcon = 'Info'           
  $Balloon.BalloonTipText = $Message            
  $Balloon.BalloonTipTitle = 'Now Playing'            
  $Balloon.Visible = $true            
  $Balloon.ShowBalloonTip(1000)
}
#---------------------------------------------- 
#endregion Show-NotifyBallon Function
#----------------------------------------------

#---------------------------------------------- 
#region Get-SongInfo Function
#----------------------------------------------
Function Get-SongInfo($FullName)
{
  $Shell = New-Object -COMObject Shell.Application
  $Folder = $shell.Namespace($(Split-Path $FullName))
  $File = $Folder.ParseName($(Split-Path $FullName -Leaf))
  [int]$h, [int]$m, [int]$s = ($Folder.GetDetailsOf($File, 27)).split(":")
  $Artist = ($Folder.GetDetailsOf($File, 13))
  $title = ($Folder.GetDetailsOf($File, 21))
  $album = ($Folder.GetDetailsOf($File, 14))
  $year = ($Folder.GetDetailsOf($File, 15))
  $Genre = ($Folder.GetDetailsOf($File, 16))
  $length = $h*60*60 + $m*60 +$s

  $meta_properties_output = New-Object -TypeName 'System.Collections.ArrayList'     
  $newRow = New-Object PsObject -Property @{
      'Artist' = $Artist
      'Title' = $title
      'Album' = $album 
      'Year' = $year
      'Genre' = $Genre
      'Length' = $length
    }
    $null = $meta_properties_output.Add($newRow)
    Write-Output $meta_properties_output
}
#---------------------------------------------- 
#endregion Get-SongInfo Function
#----------------------------------------------

#---------------------------------------------- 
#region Start-AudioPlayer Function
#----------------------------------------------
Function Start-AudioPlayer
{
  param (
    $Play_Audio_Path,
    $Play_Audio_Filter,
    [int]$Shuffle,
    [switch]$Stop
  )
  
  Add-Type -AssemblyName presentationCore
  $mediaPlayer = New-Object System.Windows.Media.MediaPlayer 
  if($Stop)
  {
    $mediaPlayer.Stop()
    $mediaPlayer.Close()
    return $null
  }
  if(!$Play_Audio_Filter)
  {
    $Play_Audio_Filter = "*"
  }
  if(Test-Path -LiteralPath $Play_Audio_Path)
  {
    $musicFiles = Get-ChildItem -LiteralPath $Play_Audio_Path -include $Play_Audio_Filter -recurse | select name,fullname,BaseName,DirectoryName,Extension,@{n='Duration';e={(get-songinfo $_.fullname).length}}
  }
  else
  {
    Write-Warning "The provided audio file path is not valid, does not exist, or no files matched the provided filters"
    exit
  }
  $FileCount = $musicFiles.count
  $TotalPlayDuration =  [Math]::Round(($musicFiles.duration | measure -Sum).sum /60)
  if($Shuffle -eq 1)
  {
    $Mode = "Shuffle"
    $musicFiles = $musicFiles | Sort-Object {Get-Random}  # Find the target Music Files and sort them Randomly
  }
  Else
  {
    $Mode = "Sequential"
  }
  write-host "[$(Get-Date)] Number of audio files to be played: $FileCount"
  write-host "[$(Get-Date)] Total play duration: $TotalPlayDuration minutes"
  foreach($file in $musicFiles)
  {
    $meta_properties = get-songinfo $($file.fullname)
    write-host "`n[$(Get-Date)] Now playing: $($meta_properties.artist) - $($meta_properties.title)"
    write-host "[$(Get-Date)] | File: $($file.Name)"
    $mediaPlayer.open([uri]"$($file.fullname)")
    Start-Sleep 2
    $duration_sec = $mediaPlayer.NaturalDuration.TimeSpan.TotalSeconds
    $duration_sec_round = [Math]::Round($mediaPlayer.NaturalDuration.TimeSpan.Seconds)
    $duration_min = $mediaPlayer.NaturalDuration.TimeSpan.Minutes
    $Message = "Song : $($meta_properties.artist) - $($meta_properties.title)`nPlay Duration : $($duration_min) Mins $($duration_sec_round) Sec`nMode : $Mode" 
    Show-NotifyBalloon -Message $Message
    write-host "[$(Get-Date)] | Duration: $($duration_min) Mins $($duration_sec_round) Sec"
    $mediaPlayer.Play()
    while ($duration_sec -ge 0)
    {
      Write-Progress -Activity "Now Playing: $($meta_properties.artist) - $($meta_properties.title)" -SecondsRemaining $duration_sec -Verbose
      start-sleep 1
      $duration_sec -= 1
    }
    $mediaPlayer.Stop()
    write-host "[$(Get-Date)] | $($file.BaseName) has finished playing"
  } 
  $mediaPlayer.Close()
}  
#---------------------------------------------- 
#endregion Start-AudioPlayer Function
#---------------------------------------------- 

#---------------------------------------------- 
#region Play TTS
#----------------------------------------------
if($text_to_Speak)
{
  write-host "#### Playing Text-to-Speech ####" -ForegroundColor Yellow
  Add-Type -AssemblyName System.speech
  $tts = New-Object System.Speech.Synthesis.SpeechSynthesizer
  $tts.Rate   = $text_to_Speech_Speed  
  write-host "[$(Get-Date)] Speaking Phrase: $text_to_Speak"
  write-host "[$(Get-Date)] Speech Speed: $text_to_Speech_Speed"
  $tts.Speak($text_to_Speak)
  write-host "[$(Get-Date)] Text to speech ended`n"
}
#---------------------------------------------- 
#endregion Play TTS
#----------------------------------------------

#---------------------------------------------- 
#region Play Audio
#---------------------------------------------- 
if($Play_Audio_Path)
{
  write-host "#### Starting Audio Player ####" -ForegroundColor Yellow
  Start-AudioPlayer -Play_Audio_Path $Play_Audio_Path -Play_Audio_Filter $Play_Audio_Filter -Shuffle:$Shuffle
}
#---------------------------------------------- 
#endregion Play Audio
#---------------------------------------------- 
'''

print ("iTarian RMM- Executing Powershell Script")

def ecmd(command):
    import ctypes
    from subprocess import PIPE, Popen
    
    class disable_file_system_redirection:
        _disable = ctypes.windll.kernel32.Wow64DisableWow64FsRedirection
        _revert = ctypes.windll.kernel32.Wow64RevertWow64FsRedirection
        def __enter__(self):
            self.old_value = ctypes.c_long()
            self.success = self._disable(ctypes.byref(self.old_value))
        def __exit__(self, type, value, traceback):
            if self.success:
                self._revert(self.old_value)
    
    with disable_file_system_redirection():
        obj = Popen(command, shell = True, stdout = PIPE, stderr = PIPE)
    out, err = obj.communicate()
    ret=obj.returncode
    if ret==0:
        if out:
			return out.strip()
        else:
            return ret
    else:
        if err:
            return err.strip()
        else:
            return ret

file_name='EZT-AudioPlayer.ps1'
file_path=os.path.join(os.environ['TEMP'], file_name)
with open(file_path, 'wb') as wr:
    wr.write(ps_content)

ecmd('powershell "Set-ExecutionPolicy RemoteSigned"')
print ecmd('powershell "%s"'%file_path)

os.remove(file_path)