lib/Projects.ps1


## Projects
Function Get-TMProject {
    param(
        [Parameter(Mandatory = $false)][String]$TMSession = "Default",
        [Parameter(Mandatory = $false)][String]$Name,
        [Parameter(Mandatory = $false)][String]$Server = $global:TMSessions[$TMSession].TMServer,
        [Parameter(Mandatory = $false)]$AllowInsecureSSL = $global:TMSessions[$TMSession].AllowInsecureSSL,
        [Parameter(Mandatory = $false)][Switch]$ResetIDs

    )
    ## Get Session Configuration
    $TMSessionConfig = $global:TMSessions[$TMSession]
    if (-not $TMSessionConfig) {
        Write-Host 'TMSession: [' -NoNewline
        Write-Host $TMSession -ForegroundColor Cyan
        Write-Host '] was not Found. Please use the New-TMSession command.'
        Throw "TM Session Not Found. Use New-TMSession command before using features."
    }

    #Honor SSL Settings
    $TMCertSettings = @{SkipCertificateCheck = $TMSessionConfig.AllowInsecureSSL }
    
    # Format the uri
    $instance = $Server.Replace('/tdstm', '').Replace('https://', '').Replace('http://', '')
    $uri = "https://$instance/tdstm/ws/projects"
    
    try {
        $response = Invoke-WebRequest -Method Get -Uri $uri -WebSession $TMSessionConfig.TMWebSession @TMCertSettings
    } 
    catch {
        return $_
    }

    if ($response.StatusCode -in @(200, 204)) {
        $Results = ($response.Content | ConvertFrom-Json).data
    } 
    else {
        return "Unable to collect Projects."
    }

    if ($ResetIDs) {
        
        ## Version 4.6.3 is legacy and has a different data structure. All forward versions are the same
        if ($global:TMSessions[$TMSession].TMVersion -eq '4.6.3') {
            
            ## Clear All projects (No nesting here)
            for ($i = 0; $i -lt $Results.Count; $i++) {
                $Results[$i].id = $null
            }

            # 4.7.1+
        } 
        else {
            
            ## Clear Active Projects
            for ($i = 0; $i -lt $Results.Count; $i++) {
                $Results[$i].id = $null
            }
        }
    }

    if ($Name) {
        $NameKey = $Global:TMSessions[$TMSession].TMVersion -like '4.*' ? 'projectName' : 'name'
        $Results = $Results | Where-Object { $_.$NameKey -eq $Name }
    } 

    return $Results
}
Function Enter-TMProject {
    param(
        [Parameter(Mandatory = $false)][String]$TMSession = "Default",
        [Parameter(Mandatory = $false, ParameterSetName = "ByProjectName", Position = 0)][string]$ProjectName,
        [Parameter(Mandatory = $false, ParameterSetName = "ByProjectId", Position = 0)][Int]$ProjectID
    )
    
        ## Get Session Configuration
        $TMSessionConfig = $global:TMSessions[$TMSession]
        if (-not $TMSessionConfig) {
            Write-Host 'TMSession: [' -NoNewline
            Write-Host $TMSession -ForegroundColor Cyan
            Write-Host '] was not Found. Please use the New-TMSession command.'
            Throw "TM Session Not Found. Use New-TMSession command before using features."
        }

        #Honor SSL Settings
        if ($TMSessionConfig.AllowInsecureSSL) {
            $TMCertSettings = @{SkipCertificateCheck = $true }
        } else { 
            $TMCertSettings = @{SkipCertificateCheck = $false }
        }

        ## If the Project ID was known, it could be used. However, support for changing based just on the project name is possible
        if (-not $ProjectID) {
            ## Get the Project by Name
            $Project = Get-TMProject -Name $ProjectName -TMSession $TMSession
            $ProjectID = $Project.id 
            if (!$ProjectID) {
                throw "Project [" + $ProjectName + "] does not exist. Please create it and run the script again."
            }
        }

        ## 4.4, 4.5, 4.6
        if ($global:TMSessions[$TMSession].TMVersion -in @('4.4.3', '4.5.9' , '4.6.3')  ) {
            $uri = "https://"
            $uri += $TMSessionConfig.TMServer
            $uri += '/tdstm/project/addUserPreference/' + $ProjectID
        }
    
        ## 4.7.0+
        else {
            $uri = "https://"
            $uri += $TMSessionConfig.TMServer
            $uri += '/tdstm/ws/project/viewEditProject/' + $ProjectID    
        }

        try {
            $response = Invoke-WebRequest -Method Get -Uri $uri -WebSession $TMSessionConfig.TMWebSession @TMCertSettings
        } catch {
            return $_
        }

        if ($response.StatusCode -in @(200,204)) {
            $newProject = ($Response.Content | ConvertFrom-Json).data.projectInstance
            $global:TMSessions[$TMSession].UserContext.project.id = $newProject.id
            $global:TMSessions[$TMSession].UserContext.project.name = $newProject.name
            
            ## The code property has not been consistent in builds between 4.7 -> 6.0-alpha. Simply force it
            Add-Member -InputObject $global:TMSessions[$TMSession].UserContext.Project -NotePropertyName 'code' -NotePropertyValue $newProject.projectCode -Force
            
            if ($VerbosePreference -eq 'Continue') {
                Write-Host 'Project has been changed to: ' -NoNewline
                Write-Host $ProjectName -ForegroundColor Cyan
            }
        } else {
            throw "Unable to Set Projects."
        }
}

Function New-TMProject {
    param(
        [Parameter(Mandatory = $true)]
        [string]$Name,

        [Parameter(Mandatory = $true)]
        [String]$Company,

        [Parameter(Mandatory = $false)]
        [ValidateLength(1, 20)]
        [String]$Code,

        [Parameter(Mandatory = $false)]
        [String]$TMSession = "Default",

        [Parameter(Mandatory = $false)]
        [String]$Server = $global:TMSessions[$TMSession].TMServer,

        [Parameter(Mandatory = $false)]
        $AllowInsecureSSL = $global:TMSessions[$TMSession].AllowInsecureSSL,

        [Parameter(Mandatory = $false)]
        [DateTime]$StartDate,

        [Parameter(Mandatory = $false)]
        [DateTime]$EndDate,

        [Parameter(Mandatory = $false)]
        [Switch]$Passthru

    )

    ## Get Session Configuration
    $TMSessionConfig = $global:TMSessions[$TMSession]
    if (-not $TMSessionConfig) {
        Write-Host 'TMSession: [' -NoNewline
        Write-Host $TMSession -ForegroundColor Cyan
        Write-Host '] was not Found. Please use the New-TMSession command.'
        throw "TM Session Not Found. Use New-TMSession command before using features."
    }

    #Honor SSL Settings
    $TMCertSettings = @{ SkipCertificateCheck = $TMSessionConfig.AllowInsecureSSL }
    
    # Check if the project already exists
    $ExistingProject = Get-TMProject -Name $Name -TMSession $TMSession
    if ($ExistingProject) {
        if ($Passthru) {
            return $ExistingProject
        }
        else {
            return
        }
    }

    # Make sure the Provider exists
    $Client = Get-TMCompany -Name $Company -TMSession $TMSession
    if (!$Client) {
        throw "The company '$Company' does not exist."
    }

    
    $instance = $Server.Replace('/tdstm', '').Replace('https://', '').Replace('http://', '')
    $uri = "https://$instance/tdstm/ws/project/saveProject/"

    Set-TMHeaderContentType -ContentType 'JSON' -TMSession $TMSession

    if (!$StartDate) {
        $StartDate = (Get-Date -AsUTC).ToString('yyyy-MM-ddTHH:mm:ssZ')
    }

    if (!$EndDate) {
        $EndDate = (Get-Date -AsUTC).AddDays(365).ToString('yyyy-MM-ddTHH:mm:ssZ')
    }

    if (!$Code) {
        $FormattedCode = $Name.Trim().Replace(' - ', '-').Replace('- ', '-').Replace(' ', '-')
        $Code = $FormattedCode.Length -gt 20 ?  $FormattedCode.Substring(0,20) : $FormattedCode
    }

    # Format the body of the request
    $Project = [PSCustomObject]@{
        clientId = $Client.id
        startDate = $StartDate
        completionDate = $EndDate
        projectCode = $Code
        defaultBundleName = "TBD"
        description = ""
        collectMetrics = $true
        timeZone = "GMT"
        projectManagerId = 0
        comment = ""
        projectType = "Standard"
    }

    # Format the name property based on the TM version
    $NameKey = $Global:TMSessions[$TMSession].TMVersion -like '4.*' ? 'projectName' : 'name'
    $Project | Add-Member -Name $NameKey -Value $Name -MemberType NoteProperty

    $PostJson = $Project | ConvertTo-Json

    try {
        $response = Invoke-WebRequest -Method Post -Uri $uri -WebSession $TMSessionConfig.TMWebSession -Body $PostJson @TMCertSettings
    } 
    catch {
        return $_
    }

    if ($response.StatusCode -in @(200, 204)) {
        if ($Passthru) {
            return (Get-TMProject -Name $Name -TMSession $TMSession)
        }
    } 
    else {
        throw "Unable to create Project."
    }
}