Microsoft.PowerPlatform.DevOps.psm1

[cmdletbinding()]
Param()

$global:devops_OldVerbose = $VerbosePreference
$VerbosePreference = $global:devops_Verbose

Write-Verbose "Importing Functions"

# Import everything in these folders
foreach ($folder in @('Private', 'Scripts')) {
    
    $root = Join-Path -Path $PSScriptRoot -ChildPath $folder
    if (Test-Path -Path $root) {
        Write-Verbose "processing folder $root"
        $files = Get-ChildItem -Path $root -Filter *.ps1

        # dot source each file
        $files | where-Object { $_.name -NotLike '*.Tests.ps1' } | 
        ForEach-Object { Write-Verbose "dot loading Library $($_.name) "; . $_.FullName }
    }
}

$global:devops_ToolPath = $PSScriptRoot 

if (!(Test-Path "$env:APPDATA\Microsoft.PowerPlatform.DevOps")) {
    New-Item -Path "$env:APPDATA\Microsoft.PowerPlatform.Devops" -ItemType Directory
}
if (!(Test-Path "$env:APPDATA\Microsoft.PowerPlatform.DevOps\devopsConfig.json")) {
    Copy-Item (Join-Path $PSScriptRoot "\devopsConfig.json") -Destination "$env:APPDATA\Microsoft.PowerPlatform.DevOps\devopsConfig.json"
}

function Show-ConfigMenu {
    Get-ConfigMenu
    $configSelection = Read-Host "Selection"
    try {
        switch ($configSelection) {
            'G' {
                try {
                    code $env:APPDATA\Microsoft.PowerPlatform.DevOps\devopsConfig.json    
                }
                catch {
                    try {
                        notepad $env:APPDATA\Microsoft.PowerPlatform.DevOps\devopsConfig.json    
                    }
                    catch {
                        try {
                            nano $env:APPDATA\Microsoft.PowerPlatform.DevOps\devopsConfig.json    
                        }
                        catch {
                            Write-Error $_
                            Write-Host ""
                            Write-Host "Please re-run Pre-requisite installation" -ForegroundColor Green
                            pause
                        }  
                    }  
                }              
            } 'P' {
                try {
                    code $global:devops_projectLocation\$global:devops_gitRepo.json        
                }
                catch {
                    try {
                        notepad $global:devops_projectLocation\$global:devops_gitRepo.json        
                    }
                    catch {
                        try {
                            nano $global:devops_projectLocation\$global:devops_gitRepo.json        
                        }
                        catch {
                            Write-Error $_ 
                            Write-Host ""
                            Write-Host "Please re-run Pre-requisite installation" -ForegroundColor Green
                            pause                                                
                        }                                                
                    }                    
                }
                
            } 'A' {
                Set-AzureKeyVault
            } 'C' {
                Set-ServicePrincipal
            } 'L' {
                $global:devops_HasDataverseLogin = $false
                Get-DataverseLogin
            } 'R' {
                Get-AzureAccounts
                #Get Access Token
                Write-Host "Getting Updated Access Token"
                $azureDevopsResourceId = "499b84ac-1321-427f-aa17-267ca6975798"
                $token = az account get-access-token --resource $azureDevopsResourceId | ConvertFrom-Json
                $authValue = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes(":" + $token.accessToken))    

                $REPO_URL = git remote get-url origin
                Write-Host "git URL is $REPO_URL"

                git config http.$REPO_URL.extraHeader "Authorization:Basic $authValue"
                Write-Host "Updated Auth Token"
                pause

            }
        }            
    }
    catch {
        Write-Host $_
        pause
    }
}

function Invoke-PowerPlatformDevOps {
    Param(
        [string] [Parameter(Mandatory = $false)] $PreLoadProjectPath = "",
        [string] [Parameter(Mandatory = $false)] $PreLoadedProjectName = "",
        [string] [Parameter(Mandatory = $false)] $PreSelection = ""
    )


    <#
        .SYNOPSIS
        Invokes and initiate the Powerplatform DevOps toolkit
 
        .DESCRIPTION
        Manage your Powerplatform Development environment
 
        .PARAMETER PreLoadProjectPath
        Specifies the file name.
 
        .PARAMETER PreSelection
        Specifies the extension. "Txt" is the default.
 
        .INPUTS
        None.
 
        .OUTPUTS
        None.
 
        .EXAMPLE
        PS> Invoke-PowerplatformDevops
         
        .EXAMPLE
        PS> ppdo
                 
        .LINK
        Online version: https://github.com/dylanhaskins/Microsoft.PowerPlatform.DevOps.Documentation
         
    #>

    $datePart = (Get-Date).ToString("yyyy_MM_dd_hhtt")
    Start-Transcript -Append -Path $env:APPDATA\Microsoft.PowerPlatform.DevOps\Logs\$($datePart)_log.txt

    Write-Host "Checking for updated versions...."
    if ((Get-Module -Name PowerShellGet).Version -gt [version]"2.0.0") {
        $latestVersion = (Find-Module Microsoft.PowerPlatform.DevOps -Repository "PSGallery" -AllowPrerelease).Version    
    }
    else {
        $latestVersion = (Find-Module Microsoft.PowerPlatform.DevOps -Repository "PSGallery").Version    
    }
    if ($latestVersion -gt $global:devops_version) {
        Update-Module Microsoft.PowerPlatform.DevOps    
        Write-Host "Updated to $latestVersion, please restart the tool for it to take effect."                
    }

    Write-Verbose "Clearing devops_ Global Variables"
    Clear-Variable devops_* -Scope Global
    
    Install-ConfigMigrationModule
    Install-XrmModule
    Install-PowerAppsAdmin
    Install-PowerAppsCheckerModule

    # Set-ToolVariables
    # Set-ProjectVariables

    if ($PreLoadProjectPath -ne "") {
        if ((Test-Path -Path "$PreLoadProjectPath\$PreLoadedProjectName.json")) {
            $global:devops_projectLocation = "$PreLoadProjectPath"
    
            $global:devops_projectFile = Get-Content ("$PreLoadProjectPath\$PreLoadedProjectName.json") | ConvertFrom-Json
            $global:devops_gitRepo = $global:devops_projectFile.gitRepo
            Set-Location  $global:devops_projectLocation
        }  
    }

    Write-Host ""
    [console]::ForegroundColor = "White"
    do {
        Get-MainMenu

        if ($PreSelection -ne "") {
            $selection = $PreSelection
            $global:devops_devMode = $true
            $PreSelection = ""
            Write-Host "Performing your Automated Selection ..."
            Start-Sleep -Seconds 2
        }
        else {
            $selection = Read-Host "Please make a selection"            
        }
        try {
            switch ($selection) {
                '1' {
                    Install-PreReqs
                } '2' {
                    Add-Project
                } '3' {
                    Connect-SourceControl
                } '4' {
                    Add-CICDEnvironment
                } 'A' {
                    Add-Solution
                } 'M' {
                    Select-Solution
                } 'S' {
                    Sync-Solution
                } 'V' {
                    Show-SolutionChanges
                } 'T' {
                    $CreateOrSelectEnv = Read-Host -Prompt "Target Environment : Would you like to [P]rovision a new Power Platform Environment ? or [S]elect an Existing One (Default [S])"
                    if ($CreateOrSelectEnv -eq "P") {
                        Add-Environment
                        Invoke-ConfigureTargetEnvironment
                    }
                    else {
                        Invoke-ConfigureTargetEnvironment
                    }                
                } 'A' {
                    # Enable-AzureDeploy
                } 'F' {
                    # Enable-FunctionApp
                } 'U' {
                    Write-Host "Checking for updated versions...."
                    $latestVersion = (Find-Module Microsoft.PowerPlatform.DevOps -Repository "PSGallery").Version
                    if ($latestVersion -gt $global:devops_version) {
                        Update-Module Microsoft.PowerPlatform.DevOps    
                        Write-Host "Updated to $latestVersion, please restart the tool for it to take effect."                
                    }
                } 'O' {
                    Invoke-OpenSolution
                } 'C' {
                    Show-ConfigMenu
                } 'R' {
                    Get-DataverseLogin
                    Get-DeployEnvironments                    
                }
            }
            Write-Host ""
        }
        catch {
            Write-Host $_
        }

    }
    until ($selection -eq 'q')
    $VerbosePreference = 'SilentlyContinue'
    Clear-Variable devops_* -Scope Global
    if (!$VerbosePreference -eq "Continue") {
        Clear-Host    
    
    }
    Stop-Transcript
    #return
    Stop-Process -Id $PID
}

function Test-IsGuid {
    [OutputType([bool])]
    param
    (
        [Parameter(Mandatory = $true)]
        [string]$StringGuid
    )
 
    $ObjectGuid = [System.Guid]::empty
    return [System.Guid]::TryParse($StringGuid, [System.Management.Automation.PSReference]$ObjectGuid) # Returns True if successfully parsed
}

Export-ModuleMember -Function 'Invoke-PowerPlatformDevOps' -Alias ppdo
Export-ModuleMember -Function 'Test-IsGuid'
Export-ModuleMember -Function 'Start-DeploySolution'
Export-ModuleMember -Function 'Start-SolutionChecker'
New-Alias -Name ppdo -Value Invoke-PowerPlatformDevOps -Scope Global
New-Alias -Name Deploy-Solution -Value Start-DeploySolution -Scope Global