BitbucketServerAutomation.psm1

# Copyright 2016 - 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Functions should use $moduleRoot as the relative root from which to find
# things. A published module has its function appended to this file, while a
# module in development has its functions in the Functions directory.
$moduleRoot = $PSScriptRoot

# Store each of your module's functions in its own file in the Functions
# directory. On the build server, your module's functions will be appended to
# this file, so only dot-source files that exist on the file system. This allows
# developers to work on a module without having to build it first. Grab all the
# functions that are in their own files.
$functionsPath = Join-Path -Path $moduleRoot -ChildPath 'Functions\*.ps1'
if( (Test-Path -Path $functionsPath) )
{
    foreach( $functionPath in (Get-Item $functionsPath) )
    {
        . $functionPath.FullName
    }
}



# Copyright 2016 - 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function Add-PSTypeName
{
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
        $InputObject,

        [Parameter(Mandatory=$true,ParameterSetName='RepositoryInfo')]
        [Switch]
        $RepositoryInfo,

        [Parameter(Mandatory=$true,ParameterSetName='ProjectInfo')]
        [Switch]
        $ProjectInfo,

        [Parameter(Mandatory=$true,ParameterSetName='CommmitBuildStatusInfo')]
        [Switch]
        $CommitBuildStatusInfo
    )

    process
    {
        Set-StrictMode -Version 'Latest'

        $typeName = 'Atlassian.Bitbucket.Server.{0}' -f $PSCmdlet.ParameterSetName
        $InputObject.pstypenames.Add( $typeName )

        if( $ProjectInfo )
        {
            if( -not ($InputObject | Get-Member -Name 'description') )
            {
                $InputObject | Add-Member -MemberType NoteProperty -Name 'description' -Value ''
            }
        }

        $InputObject
    }
}

# Copyright 2016 - 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function Disable-BBServerHook
{
    <#
    .SYNOPSIS
    Disables a hook in a repository.
 
    .DESCRIPTION
    The `Disable-BBServerHook` function sets the value of the `Enabled` property to `false` for a designated hook in a Bitbucket Server repository.
     
    If you pass a hook key that does not exist in the target repository, an error will be thrown.
 
    .EXAMPLE
    Disable-BBServerHook -Connection $conn -ProjectKey 'TestProject' -RepoName 'TestRepo' -HookKey 'com.atlassian.bitbucket.server.example-hook-key'
 
    Demonstrates how to disable a hook with key `com.atlassian.bitbucket.server.example-hook-key` in the `TestRepo` repository.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [object]
        # An object that defines what Bitbucket Server to connect to and the credentials to use when connecting.
        $Connection,

        [Parameter(Mandatory=$true)]
        [string]
        # The key/ID that identifies the project where the repository resides. This is *not* the project name.
        $ProjectKey,

        [Parameter(Mandatory=$true)]
        [string]
        # The name of a specific repository.
        $RepoName,

        [Parameter(Mandatory=$true)]
        [string]
        # The name of the repository hook to disable.
        $HookKey
    )
    
    Set-StrictMode -Version 'Latest'
    Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState
    
    $resourcePath = ('projects/{0}/repos/{1}/settings/hooks/{2}/enabled' -f $ProjectKey, $RepoName, $HookKey)
    
    Invoke-BBServerRestMethod -Connection $Connection -Method 'DELETE' -ApiName 'api' -ResourcePath $resourcePath
}


# Copyright 2016 - 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function Enable-BBServerHook
{
    <#
    .SYNOPSIS
    Enables a hook in a repository.
 
    .DESCRIPTION
    The `Enable-BBServerHook` function sets the value of the `Enabled` property to `true` for a designated hook in a Bitbucket Server repository.
     
    If you pass a hook key that does not exist in the target repository, an error will be thrown.
 
    .EXAMPLE
    Enable-BBServerHook -Connection $conn -ProjectKey 'TestProject' -RepoName 'TestRepo' -HookKey 'com.atlassian.bitbucket.server.example-hook-key'
 
    Demonstrates how to enable a hook with key `com.atlassian.bitbucket.server.example-hook-key` in the `TestRepo` repository.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [object]
        # An object that defines what Bitbucket Server to connect to and the credentials to use when connecting.
        $Connection,

        [Parameter(Mandatory=$true)]
        [string]
        # The key/ID that identifies the project where the repository resides. This is *not* the project name.
        $ProjectKey,

        [Parameter(Mandatory=$true)]
        [string]
        # The name of a specific repository.
        $RepoName,

        [Parameter(Mandatory=$true)]
        [string]
        # The name of the repository hook to enable.
        $HookKey
    )
    
    Set-StrictMode -Version 'Latest'
    Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState
    
    $resourcePath = ('projects/{0}/repos/{1}/settings/hooks/{2}/enabled' -f $ProjectKey, $RepoName, $HookKey)
    
    Invoke-BBServerRestMethod -Connection $Connection -Method 'PUT' -ApiName 'api' -ResourcePath $resourcePath
}


# Copyright 2016 - 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function Find-BBServerRepository
{
    param(
        [parameter(Mandatory=$true)]
        [Object]
        $Connection,
  
        # Name of a Repository you wish to find. supports Wildcards.
        [String]
        $Name
    )
    Get-BBServerProject -Connection $Connection |
        ForEach-Object { 
            return Get-BBServerRepository -Connection $Connection -ProjectKey $_.key |
                where-Object { $_.name -like $Name } 
        }
}

# Copyright 2016 - 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function Get-BBServerBranch
{
    <#
    .SYNOPSIS
    Gets a list of branches from a repository.
 
    .DESCRIPTION
    The `Get-BBServerBranch` function returns a list of all branches in a Bitbucket Server repository.
     
    If you pass a branch name, the function will only return the information for the named branch and will return nothing if no branches are found that match the search criteria. Wildcards are allowed to search for files.
 
    .EXAMPLE
    Get-BBServerBranch -Connection $conn -ProjectKey 'TestProject' -RepoName 'TestRepo'
 
    Demonstrates how to get the properties of all branches in the `TestRepo` repository.
 
    .EXAMPLE
    Get-BBServerBranch -Connection $conn -ProjectKey 'TestProject' -RepoName 'TestRepo' -BranchName 'master'
 
    Demonstrates how to get the properties for the master branch in the `TestRepo` repository.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [object]
        # An object that defines what Bitbucket Server to connect to and the credentials to use when connecting.
        $Connection,

        [Parameter(Mandatory=$true)]
        [string]
        # The key/ID that identifies the project where the repository resides. This is *not* the project name.
        $ProjectKey,

        [Parameter(Mandatory=$true)]
        [string]
        # The name of a specific repository.
        $RepoName,

        [string]
        # The name of the branch to search for.
        $BranchName
    )
    
    Set-StrictMode -Version 'Latest'
    Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState
    
    $resourcePath = ('projects/{0}/repos/{1}/branches' -f $ProjectKey, $RepoName)
    
    $getBranches = Invoke-BBServerRestMethod -Connection $Connection -Method 'GET' -ApiName 'api' -ResourcePath $resourcePath -IsPaged
    
    if( $BranchName )
    {
        return $getBranches | Where-Object { $_.displayId -like $BranchName }
    }
    
    return $getBranches
}


# Copyright 2016 - 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function Get-BBServerChange
{
    <#
    .SYNOPSIS
    Gets a list of Changes from two commits in a repository.
 
    .DESCRIPTION
    The `Get-BBServerChange` function returns a list of Changes from two commits in a repository.
     
    .EXAMPLE
    Get-BBServerChange -Connection $conn -ProjectKey 'TestProject' -RepoName 'TestRepo' -From "TestBranch" -To "master"
 
    Demonstrates how to get the properties of all changes between testBranch and master branches in the `TestRepo` repository.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [object]
        # An object that defines what Bitbucket Server to connect to and the credentials to use when connecting.
        $Connection,

        [Parameter(Mandatory=$true)]
        [string]
        # The key/ID that identifies the project where the repository resides. This is *not* the project name.
        $ProjectKey,

        [Parameter(Mandatory=$true)]
        [string]
        # The name of a specific repository.
        $RepoName,

        [Parameter(Mandatory=$true)]
        [string]
        # name of the source commit or Ref.
        $From,

        [Parameter(Mandatory=$true)]
        [string]
        # name of the target commit or Ref.
        $To

    )

    Set-StrictMode -Version 'Latest'
    Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState

    $lastPage = $false
    $nextPageStart = 0
    $changes = $null

    while ( -not $lastPage )
    {
        $resourcePath = ('projects/{0}/repos/{1}/compare/changes?from={2}&to={3}' -f $ProjectKey, $RepoName, [Web.HttpUtility]::UrlEncode($From), [Web.HttpUtility]::UrlEncode($To))
        $changes = Invoke-BBServerRestMethod -Connection $Connection -Method Get -ApiName 'api' -ResourcePath ('{0}&limit={1}&start={2}' -f $resourcePath, [int16]::MaxValue, $nextPageStart)
        if( $changes)
        {
            $lastPage = $changes.isLastPage
            $nextPageStart = $changes.nextPageStart
            return $changes.values
            continue
        }
        return
    }
}


# Copyright 2016 - 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function Get-BBServerCommitBuildStatus
{
    <#
    .SYNOPSIS
    Gets the build status of a commit.
 
    .DESCRIPTION
    The `Get-BBServerCommitBuildStatus` function gets the build status for a specific commit. The commit ID is the full sha1 identifer Git uses to uniquely identify a commit, e.g. `e00cf62997a027bbf785614a93e2e55bb331d268`. There may be more than one status if a commit was built multiple times.
 
    The returned object(s) will have the following properties:
 
    * `state`: Indicates whether the build passed, failed, or is in progress. Its value will be one of `SUCCESSFUL`, `INPROGRESS` or `FAILED`
    * `key`: A unique value that identifies the build. Usually only means something to the original build system.
    * `name`: The name of the build.
    * `url`: The URI to the build.
    * `description`: A description of the build.
    * `dateAdded`: The date/time the status was added to Bitbucker Server.
 
    .EXAMPLE
    Get-BBServerCommitBuildStatus -Connection $conn -CommitID 'e00cf62997a027bbf785614a93e2e55bb331d268'
 
    Demonstrates how to get the build status for a commit.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [object]
        # The connection to the Bitbucket Server. Use `New-BBServerConnection` to create one.
        $Connection,

        [Parameter(Mandatory=$true)]
        [ValidateLength(1,255)]
        [string]
        # The ID of the commit. This is the full sha1 identifer Git uses to uniquely identify a commit, e.g. `e00cf62997a027bbf785614a93e2e55bb331d268`.
        $CommitID
    )

    Set-StrictMode -Version 'Latest'
    Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState

    $epochStart = Get-Date -Year 1970 -Month 1 -Day 1 -Hour 0 -Minute 0 -Second 0 -Millisecond 0

    Invoke-BBServerRestMethod -Connection $Connection -Method Get -ApiName 'build-status' -ResourcePath ('commits/{0}' -f $CommitID) |
        Select-Object -ExpandProperty 'values' |
        Add-PSTypeName -CommitBuildStatusInfo |
        ForEach-Object { $_.dateAdded = $epochStart.AddSeconds(([double]$_.dateAdded) / 1000) ; $_ }
    
}


# Copyright 2016 - 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function Get-BBServerDefaultReviewer
{
    <#
    .SYNOPSIS
    Gets the default reviewer conditions for a project or repository.
 
    .DESCRIPTION
    The `Get-BBServerDefaultReviewer` function gets the default reviewer conditions that have been configured at either the project or repository level. When getting the default reviewer conditions for a repository, any default reviewer conditions inherited from the parent project will also be returned.
 
    .EXAMPLE
    Get-BBServerDefaultReviewer -Connection $conn -ProjectKey 'GBBSDR'
 
    Demonstrates getting all the default reviewer conditions that have been configured for the "GBBSDR" project.
 
    .EXAMPLE
    Get-BBServerDefaultReviewer -Connection $conn -ProjectKey 'GBBSDR' -RepositoryName 'Scripts'
 
    Demonstrates getting all the default reviewer conditions that have been configured for the "Scripts" repository, including any inherited conditions from its parent "GBBSDR" project.
    #>

    param(
        [Parameter(Mandatory)]
        [object]
        # An object that defines what Bitbucket Server to connect to and the credentials to use when connecting. Use `New-BBServerConnection` to create connection objects.
        $Connection,

        [Parameter(Mandatory)]
        [string]
        # The key/ID that identifies the project. This is *not* the project name.
        $ProjectKey,

        [string]
        # The name of a repository in the project.
        $RepositoryName
    )

    Set-StrictMode -Version 'Latest'
    Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState

    $resourcePath = 'projects/{0}/conditions' -f $ProjectKey
    if ($RepositoryName)
    {
        $resourcePath = 'projects/{0}/repos/{1}/conditions' -f $ProjectKey, $RepositoryName
    }

    Invoke-BBServerRestMethod -Connection $Connection -Method Get -ApiName 'default-reviewers' -ResourcePath $resourcePath
}


# Copyright 2016 - 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function Get-BBServerFile
{
    <#
    .SYNOPSIS
    Gets a list of files from a repository.
 
    .DESCRIPTION
    The `Get-BBServerFile` function returns a list of all files in a Bitbucket Server repository.
 
    To get only files under part of a repository, pass its path to the `Path` parameter. The path should be relative to the root of the repository.
     
    To search for files, use the `Filter` parameter. Pass it the path to a specific file, or a wildcard pattern that matches multiple files. `Get-BBServerFile` uses PowerShell's `-like` operator to do the comparison.
 
    Note that when using the `Path` parameter, the Bitbucket Server API treats that path as if it were the root of the repository. Paths returns will not have `Path` at the beginning of the path. Filters that include `Path` will not match anything.
 
    .EXAMPLE
    Get-BBServerFile -Connection $conn -ProjectKey 'TestProject' -RepoName 'TestRepo'
 
    Demonstrates how to get a list of all the files `TestRepo` repository.
 
    .EXAMPLE
    Get-BBServerFile -Connection $conn -ProjectKey 'TestProject' -RepoName 'TestRepo' -Filter 'publish.ps1'
 
    Demonstrates how to get a specific file. In this case, only a file named `publish.ps1` in the root of the repository, is returned.
 
    .EXAMPLE
    Get-BBServerFile -Connection $conn -ProjectKey 'TestProject' -RepoName 'TestRepo' -Filter 'BitbucketServerAutomation/BitbucketServerAutomation.psd1'
 
    Demonstrates how to get a specific file. In this case, only a file `BitbucketServerAutomation/BitbucketServerAutomation.psd1` will be returned, if it exists.
 
    .EXAMPLE
    Get-BBServerFile -Connection $conn -ProjectKey 'TestProject' -RepoName 'TestRepo' -Filter '*.txt'
 
    Demonstrates how to get all files that match a wildcard. In this case, all files whose paths end in `.txt` will be returned. Uses PowerShell's `-like` operator.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [object]
        # An object that defines what Bitbucket Server to connect to and the credentials to use when connecting.
        $Connection,

        [Parameter(Mandatory=$true)]
        [string]
        # The key/ID that identifies the project where the repository resides. This is *not* the project name.
        $ProjectKey,

        [Parameter(Mandatory=$true)]
        [string]
        # The name of a specific repository.
        $RepoName,

        [string]
        # The path where the search should start. By default the root of the repository is used so the whole repository is searched. Use this parameter to only search part of the repository.
        $Path,

        [string]
        # Only returns files whose paths match this filter. Wildcards are supported.
        $Filter
    )
    
    Set-StrictMode -Version 'Latest'
    Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
    
    $resourcePath = ('projects/{0}/repos/{1}/files/{2}' -f $ProjectKey, $RepoName, $Path)
    Invoke-BBServerRestMethod -Connection $Connection -Method 'GET' -ApiName 'api' -ResourcePath $resourcePath -IsPaged | 
        Where-Object {
            if( $Filter )
            {
                return $_ -like $Filter
            }
            return $true
        }
}


# Copyright 2016 - 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function Get-BBServerFileContent
{
    <#
    .SYNOPSIS
    Gets the raw content of a file in a repository.
     
    .DESCRIPTION
    The `Get-BBServerFileContent` function gets the raw content of a file from a repository. Pass the connection to the
    Bitbucket Server to the `Connection` object. Pass the project key of the repository to the `ProjectKey` parameter.
    Pass the repository name to the `RepoName` parameter. Pass the path to the file in the repository to the `Path`
    parameter. The raw content of the file is returned.
 
    To retrieve the value of the file at a specific commit, pass the commitish identifier (a tag, hash, branch name,
    etc.) to the `Commitish` parameter.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        # An object that defines what Bitbucket Server to connect to and the credentials to use when connecting.
        [Object]$Connection,

        [Parameter(Mandatory)]
        # The key/ID that identifies the project where the repository resides. This is *not* the project name.
        [String]$ProjectKey,

        [Parameter(Mandatory)]
        # The name of a specific repository.
        [String]$RepoName,

        [Parameter(Mandatory)]
        # The path of the file in the repository. Use forward-slashes for directory separators.
        [String]$Path,

        # The commit at which to get the file's contents.
        [String]$Commitish
    )

    Set-StrictMode -Version 'Latest'
    Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
    
    $Path = "projects/$($ProjectKey)/repos/$($RepoName)/raw/$($Path)"

    $parameter = @{}
    if( $Commitish )
    {
        $parameter['at'] = $Commitish
    }

    Invoke-BBServerRestMethod -Connection $Connection `
                              -Method Get `
                              -ApiName 'api' `
                              -ResourcePath $Path `
                              -Parameter $parameter
}

# Copyright 2016 - 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function Get-BBServerHook
{
    <#
    .SYNOPSIS
    Gets a list of hooks from a repository.
 
    .DESCRIPTION
    The `Get-BBServerHook` function returns a list of all hooks in a Bitbucket Server repository.
     
    If you pass a hook key, the function will only return the information for the named hook and will return nothing if no hooks are found that match the search criteria. Wildcards are allowed for hook keys.
 
    .EXAMPLE
    Get-BBServerHook -Connection $conn -ProjectKey 'TestProject' -RepoName 'TestRepo'
 
    Demonstrates how to get the properties of all hooks in the `TestRepo` repository.
 
    .EXAMPLE
    Get-BBServerHook -Connection $conn -ProjectKey 'TestProject' -RepoName 'TestRepo' -HookKey 'com.atlassian.bitbucket.server.example-hook-key'
 
    Demonstrates how to get the properties of the 'com.atlassian.bitbucket.server.example-hook-key' hook in the `TestRepo` repository.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [object]
        # An object that defines what Bitbucket Server to connect to and the credentials to use when connecting.
        $Connection,

        [Parameter(Mandatory=$true)]
        [string]
        # The key/ID that identifies the project where the repository resides. This is *not* the project name.
        $ProjectKey,

        [Parameter(Mandatory=$true)]
        [string]
        # The name of a specific repository.
        $RepoName,

        [string]
        # The name of the hook to search for.
        $HookKey
    )
    
    Set-StrictMode -Version 'Latest'
    Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState
    
    $resourcePath = ('projects/{0}/repos/{1}/settings/hooks' -f $ProjectKey, $RepoName)
    
    $getHooks = Invoke-BBServerRestMethod -Connection $Connection -Method 'GET' -ApiName 'api' -ResourcePath $resourcePath -IsPaged
    
    if( $HookKey )
    {
        return $getHooks | Where-Object { $_.details.key -like $HookKey }
    }
    else
    {
        return $getHooks
    }
}


# Copyright 2016 - 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function Get-BBServerProject
{
    <#
    .SYNOPSIS
    Gets projects.
 
    .DESCRIPTION
    The `Get-BBServerProject` function gets all projects in a Bitbucket Server instance. If you pass it a name, it will get just that project. Wildcards are allowed to search for projects. Wildcard matching is *not* supported by the Bitbucket Server API, so all projects must be retrieved and searched.
 
    .LINK
    https://confluence.atlassian.com/bitbucket/projects-792497956.html
 
    .EXAMPLE
 
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [object]
        # An object that defines what Bitbucket Server to connect to and the credentials to use when connecting.
        $Connection,

        [string]
        # The name of the project to get. Wildcards allowed. The wildcard search is done on the *client* (i.e. this computer) not the server. All projects are fetched from Bitbucket Server first. This may impact performance.
        $Name
    )
    
    Set-StrictMode -Version 'Latest'
    Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState

    $resourcePath = 'projects'
    if( $Name )
    {
        $resourcePath = '{0}?name={1}' -f $resourcePath,$Name
    }
    else
    {
        $resourcePath = '{0}?limit={1}' -f $resourcePath,[int16]::MaxValue
    }

    Invoke-BBServerRestMethod -Connection $Connection -Method Get -ApiName 'api' -ResourcePath $resourcePath  |
        Select-Object -ExpandProperty 'values' |
        Add-PSTypeName -ProjectInfo
}

# Copyright 2016 - 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function Get-BBServerPullRequest
{
    <#
    .SYNOPSIS
    Gets pull requests
 
    .DESCRIPTION
    The `Get-BBServerPullRequest` function gets all pull requests in a Bitbucket Server instance. If you pass it an id, it will get just the pull request with that id.
 
 
    .EXAMPLE
    Get-BBServerPullRequest -Connection $bbConnection -ProjectKey $projectKey -RepoName $repoName -id $ID
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [object]
        # An object that defines what Bitbucket Server to connect to and the credentials to use when connecting.
        $Connection,

        [string]
        # The id of the pull request to get, if this is not included the default will be to get all current pull requests
        $ID = "",

        [Parameter(Mandatory=$true)]
        [string]
        # The key/ID that identifies the project where the repository will be created. This is *not* the project name.
        $ProjectKey,

        [Parameter(Mandatory=$true)]
        [string]
        # The name of a specific repository.
        $RepoName        
    )
    
    Set-StrictMode -Version 'Latest'
    Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState
    
    $ResourcePath = ('projects/{0}/repos/{1}/pull-requests/{2}' -f $ProjectKey, $RepoName, $ID)
    
    return Invoke-BBServerRestMethod -Connection $Connection -Method Get -ApiName 'api' -ResourcePath $ResourcePath 
}


# Copyright 2016 - 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function Get-BBServerPullRequestSetting
{
    <#
    .SYNOPSIS
    Gets a list of pull request settings from a repository.
     
    .DESCRIPTION
    The `Get-BBServerPullRequestSetting` function returns a list of all pull request settings in a Bitbucket Server repository.
     
    If you pass a setting name, the function will only return the information for the named setting. It will return an error if no setting exists that match the search criteria.
 
    .EXAMPLE
    Get-BBServerPullRequestSetting -Connection $conn -ProjectKey 'TestProject' -RepoName 'TestRepo'
 
    Demonstrates how to get all pull request settings in the `TestRepo` repository.
 
    .EXAMPLE
    Get-BBServerPullRequestSetting -Connection $conn -ProjectKey 'TestProject' -RepoName 'TestRepo' -SettingName 'RequiredApprovers'
 
    Demonstrates how to get `RequiredApprovers` setting in the `TestRepo` repository.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [object]
        # An object that defines what Bitbucket Server to connect to and the credentials to use when connecting.
        $Connection,

        [Parameter(Mandatory=$true)]
        [string]
        # The key/ID that identifies the project where the repository resides. This is *not* the project name.
        $ProjectKey,

        [Parameter(Mandatory=$true)]
        [string]
        # The name of a specific repository.
        $RepoName,

        [string]
        # The name of the pull request setting to retrieve. When omitted, all settings are returned.
        $SettingName
    )
    
    Set-StrictMode -Version 'Latest'
    Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState
    
    $resourcePath = ('projects/{0}/repos/{1}/settings/pull-requests' -f $ProjectKey, $RepoName)
    $pullRequestSettings = Invoke-BBServerRestMethod -Connection $Connection -Method 'GET' -ApiName 'api' -ResourcePath $resourcePath
    
    if( $SettingName )
    {
        try
        {
            return $pullRequestSettings.('{0}' -f $SettingName)
        }
        catch
        {
            Write-Error ('''{0}'' is not a valid Pull Request configuration setting. Please enter a valid setting or omit the $SettingName parameter to return all settings.' -f $SettingName)
            return
        }
    }
    else
    {
        return $pullRequestSettings
    }
}


# Copyright 2016 - 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function Get-BBServerRepository
{
    <#
    .SYNOPSIS
    Gets Bitbucket Server repositories.
 
    .DESCRIPTION
    The `Get-BBServerRepository` function gets Bitbucket Server repositories. Only the repositories under a specific project are returned. Pass the project's key/ID whose repositories to get with the `ProjectKey` parameter.
 
    Use the `New-BBServerConnection` function to create a connection object that is passed to the `Connection` parameter.
 
    The returned objects have the following properties:
 
     * `slug`: The repository's public key/ID. Use this value when a Bitbucket Server Automation function has a `RepositorySlug` parameter.
     * `id`: Bitbucket Server's internal, numeric ID for the repository.
     * `name`
     * `scmId`: the repository's source code management system. Bitbucket Server only supports Git.
     * `state`
     * `statusMessage`
     * `forkable`: a flag that indicates if the repository supports forking
     * `project`: a project object for the repository's project
     * `public`: a flag indicating if the repository is public or not
     * `links`: an object with two properties: `clone` an array of URLs you can use to clone; and `self` an HTTP URL for viewing the repository in a web browser
 
    .EXAMPLE
    Get-BBServerRepository -Connection $conn -ProjectKey 'BBSA'
 
    Demonstrates how to get all the repositories under the `BBSA` project.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [object]
        # The connection information that describe what Bitbucket Server instance to connect to, what credentials to use, etc. Use the `New-BBServerConnection` function to create a connection object.
        $Connection,

        [Parameter(Mandatory=$true)]
        [string]
        # The key/ID that identifies the project where the repository will be created. This is *not* the project name.
        $ProjectKey,

        [string]
        # The name of a specific repository to get.
        $Name
    )

    Set-StrictMode -Version 'Latest'
    Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState
    
    $resourcePath = 'projects/{0}/repos' -f $ProjectKey
    
    $result = Invoke-BBServerRestMethod -Connection $Connection -Method Get -ApiName 'api' -ResourcePath $resourcePath -IsPaged -ErrorVariable 'errors'
    
    if( $Name )
    {
        $result | Where-Object { return $_.Name -like $Name } | Add-PSTypeName -RepositoryInfo
    }
    else
    {
    
        $result | Add-PSTypeName -RepositoryInfo
    }
}

# Copyright 2016 - 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function Get-BBServerTag 
{
    <#
    .SYNOPSIS
    Gets tags from a repository in Bitbucket Server.
 
    .DESCRIPTION
    The `Get-BBServerTag` function returns the git tags associated with a particular repository in Bitbucket Server. It will one or more of the most recent git tags in a repo, up to a max of 25, after which it will truncate the least recent tags in favor of the most recent tags. If the repo has zero tags an error will be thrown.
 
    The tags are obtained through a rest call, and the return from that call is a collection of JSON objects with the related Tag information. This is returned from `Get-BBServerTag` in the form of a list of PowerShell Objects.
 
    .EXAMPLE
    Get-BBServerTag -Connection $conn -ProjectKey $key -RepositoryKey $repoName
 
    Demonstrates how to obtain the git tags associated with a particular repository
    #>

    param(
        [Parameter(Mandatory=$true)]
        [object]
        # An object that defines what Bitbucket Server to connect to and the credentials to use when connecting.
        $Connection,    
  
        [Parameter(Mandatory=$true)]
        [string]
        # The key of the repository's project.
        $ProjectKey,
 
        [Parameter(Mandatory=$true)]
        [string]
        # The key of the repository.
        $RepositoryKey

    )
  
    Set-StrictMode -Version 'Latest'
    Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
    
    Invoke-BBServerRestMethod -Connection $Connection -Method Get -ApiName 'api' -ResourcePath ('projects/{0}/repos/{1}/tags' -f $ProjectKey, $RepositoryKey) -IsPaged
}

 


# Copyright 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function Get-BBServerUser
{
    <#
    .SYNOPSIS
    Gets a Bitbucket Server user.
 
    .DESCRIPTION
    The `Get-BBServerUser` function gets users that exist in Bitbucket Server. By default all users are returned.
 
    To get specific users, pass a string representing a username, display name, or email address to the `Filter` parameter.
 
    .EXAMPLE
    Get-BBServerUser -Connection $BBConnection
 
    Demonstrates how to get all Bitbucket Server users.
 
    .EXAMPLE
    Get-BBServerUser -Connection $BBConnection -Filter 'email.com'
 
    Demonstrates how to get all Bitbucket Server users whose email address contains "email.com".
    #>

    param(
        [Parameter(Mandatory=$true)]
        [object]
        # An object that defines what Bitbucket Server to connect to and the credentials to use when connecting.
        $Connection,

        [string]
        # Filter to use to find a specific user. This is passed to Bitbucket Server as-is. It searches a user's username, display name, and email address for the filter. If any field matches, that user is returned.
        $Filter
    )

    Set-StrictMode -Version 'Latest'
    Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState

    $requestQueryParameter = @{}
    if ($Filter)
    {
        $requestQueryParameter['Parameter'] = @{ 'filter' = $Filter }
    }

    Invoke-BBServerRestMethod -Connection $Connection -Method Get -ApiName 'api' -ResourcePath 'admin/users' -IsPaged @requestQueryParameter
}


# Copyright 2019 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function Get-DefaultReviewerBranchMatcher
{
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [string]
        # The name of the parameter that contains the branch matching type. Used for writing warning and errors messages.
        $TypeParameterName,

        [Parameter(Mandatory)]
        [string]
        # The name of the parameter that contains the branch matching value. Used for writing warning and errors messages.
        $ValueParameterName,

        [Parameter(Mandatory)]
        [ValidateSet('Any', 'Name', 'Pattern', 'Model')]
        # The type of matching for the branch.
        $Type,

        [Parameter(Mandatory)]
        [AllowEmptyString()]
        [string]
        # Specifies the value or pattern to match a branch.
        $Value
    )

    Set-StrictMode -Version 'Latest'
    Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState

    $branchingModelCategories = @('Feature', 'Bugfix', 'Hotfix', 'Release')
    $branchingModelBranches = @('Development', 'Production')
    $specificBranchTypes = @('Name', 'Pattern', 'Model')

    if ($Type -in $specificBranchTypes -and -not $Value)
    {
        Write-Error -Message ('"{0}" cannot be empty if "{1}" is one of "{2}"' -f $ValueParameterName, $TypeParameterName, ($specificBranchTypes -join ', ')) -ErrorAction $ErrorActionPreference
        return
    }

    if ($Type -eq 'Any')
    {
        if ($Value)
        {
            Write-Warning -Message ('"{0}" is "Any", ignoring "{1}" parameter.' -f $TypeParameterName, $ValueParameterName)
        }

        $matcherId = $matcherDisplayId = 'ANY_REF_MATCHER_ID'
        $matcherTypeId = 'ANY_REF'
        $matcherTypeName = 'Any branch'
    }
    elseif ($Type -eq 'Name')
    {
        $matcherId = $matcherDisplayId = $Value
        $matcherTypeId = 'BRANCH'
        $matcherTypeName = 'Branch'
    }
    elseif ($Type -eq 'Pattern')
    {
        $matcherId = $matcherDisplayId = $Value
        $matcherTypeId = 'PATTERN'
        $matcherTypeName = 'Pattern'
    }
    elseif ($Type -eq 'Model')
    {
        if ($Value -notin $branchingModelCategories -and $Value -notin $branchingModelBranches)
        {
            Write-Error -Message ('When "{0}" is "Model", parameter "{1}" must be one of "{2}, {3}"' -f $TypeParameterName, $ValueParameterName, ($branchingModelCategories -join ', '), ($branchingModelBranches -join ', ')) -ErrorAction $ErrorActionPreference
            return
        }
        elseif ($Value -in $branchingModelCategories)
        {
            $matcherId = $Value.ToUpperInvariant()
            $matcherDisplayId = $Value
            $matcherTypeId = 'MODEL_CATEGORY'
            $matcherTypeName = 'Branching model category'
        }
        elseif ($Value -in $branchingModelBranches)
        {
            $matcherId = $Value.ToLowerInvariant()
            $matcherDisplayId = $Value
            $matcherTypeId = 'MODEL_BRANCH'
            $matcherTypeName = 'Branching model branch'
        }
    }

    @{
        active = 'true'
        id = $matcherId
        displayId = $matcherDisplayId
        type = @{
            id = $matcherTypeId
            name = $matcherTypeName
        }
    }
}


# Copyright 2016 - 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function Invoke-BBServerRestMethod
{
    <#
    .SYNOPSIS
    Calls a method in the Bitbucket Server REST API.
 
    .DESCRIPTION
    The `Invoke-BBServerRestMethod` function calls a method on the Bitbucket Server REST API. You pass it a Connection object (returned from `New-BBServerConnection`), the HTTP method to use, the name of API (via the `ApiName` parametr), the name/path of the resource via the `ResourcePath` parameter, and a hashtable/object/psobject via the `InputObject` parameter representing the data to send in the body of the request. The data is converted to JSON and sent in the body of the request.
 
    A Bitbucket Server URI has the form `https://example.com/rest/API_NAME/API_VERSION/RESOURCE_PATH`. `API_VERSION` is taken from the connection object passed to the `Connection` parameter. The `API_NAME` path should be passed to the `ApiName` paramter. The `RESOURCE_PATH` path should be passed to the `ResourcePath` parameter. The base URI is taken from the `Uri` property of the connection object passed to the `Connection` parameter.
 
    .EXAMPLE
    $body | Invoke-BBServerRestMethod -Connection $Connection -Method Post -ApiName 'build-status' -ResourcePath ('commits/{0}' -f $commitID)
 
    Demonstrates how to call the /build-status API's `/commits/COMMIT_ID` resource. Body is a hashtable that looks like this:
 
        $body = @{
                    state = 'INPROGRESS';
                    key = 'MY_BUILD_KEY';
                    name = 'MY_BUILD_NAME';
                    url = 'MY_BUILD_URL';
                    description = 'MY_BUILD_DESCRIPTION';
                 }
 
    #>

    [CmdletBinding(SupportsShouldProcess)]
    param(
        [Parameter(Mandatory=$true)]
        [object]
        # The connection to use to invoke the REST method.
        $Connection,

        [Parameter(Mandatory=$true)]
        [Microsoft.PowerShell.Commands.WebRequestMethod]
        $Method,

        [Parameter(Mandatory,ParameterSetName='SimpleUri')]
        [string]
        # The name of the API being invoked, e.g. `projects`, `build-status`, etc. If the endpoint URI is `http://example.com/rest/build-status/1.0/commits`, the API name is between the `rest` and API version, which in this example is `build-status`.
        $ApiName,

        [Parameter(Mandatory,ParameterSetName='SimpleUri')]
        [string]
        # The path to the resource to use. If the endpoint URI `http://example.com/rest/build-status/1.0/commits`, the ResourcePath is everything after the API version. In this case, the resource path is `commits`.
        $ResourcePath,

        [Parameter(Mandatory,ParameterSetName='FullPath')]
        [String]$Path,

        [Parameter(ValueFromPipeline=$true)]
        [object]
        $InputObject,

        [hashtable]
        # Hashtable representing the request query parameters to include when calling the API resource.
        $Parameter,

        [switch]
        $IsPaged
    )

    Set-StrictMode -Version 'Latest'
    Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState

    if( $PSCmdlet.ParameterSetName -eq 'SimpleUri' )
    {
        $Path = 'rest/{0}/{1}/{2}' -f $ApiName.Trim('/'),$Connection.ApiVersion.Trim('/'),$ResourcePath.Trim('/')
    }

    if ($Parameter)
    {
        $requestQueryParameter = ''
        foreach ($key in $Parameter.Keys)
        {
            $requestQueryParameter += '&{0}={1}' -f [uri]::EscapeDataString($key), [uri]::EscapeDataString($Parameter[$key])
        }

        $requestQueryParameter = $requestQueryParameter.TrimStart('&')
        $Path = '{0}?{1}' -f $Path, $requestQueryParameter
    }

    $uri = New-Object 'Uri' -ArgumentList $Connection.Uri,$Path

    $bodyParam = @{ }
    if( $InputObject )
    {
        $bodyParam['Body'] = $InputObject | ConvertTo-Json -Depth 100
    }

    #$DebugPreference = 'Continue'
    Write-Debug -Message ('{0} {1}' -f $Method.ToString().ToUpperInvariant(), $uri)
    if( $bodyParam['Body'] )
    {
        Write-Debug -Message $bodyParam['Body']
    }

    $credential = $Connection.Credential
    $credential = '{0}:{1}' -f $credential.UserName,$credential.GetNetworkCredential().Password

    $authHeaderValue = 'Basic {0}' -f [Convert]::ToBase64String( [Text.Encoding]::UTF8.GetBytes($credential) )
    $headers = @{
        'Authorization' = $authHeaderValue
        'X-Atlassian-Token' = 'no-check'
    }

    try
    {
        if( $IsPaged )
        {
            $nextPageStart = 0
            $isLastPage = $false

            while( $isLastPage -eq $false )
            {
                if ($Path -match '\?')
                {
                    $queryStringSeparator = '&'
                }
                else
                {
                    $queryStringSeparator = '?'
                }

                $uriPagedPath = ('{0}{1}limit={2}&start={3}' -f $Path, $queryStringSeparator, [int16]::MaxValue, $nextPageStart)
                $uri = New-Object 'Uri' -ArgumentList $Connection.Uri,$uriPagedPath

                $getStream = Invoke-RestMethod -Method $Method -Uri $uri -Headers $headers -ContentType 'application/json' @bodyParam -ErrorVariable 'errors'
                if( $getStream.isLastPage -eq $false )
                {
                    $nextPageStart = $getStream.nextPageStart
                }
                else
                {
                    $isLastPage = $true
                }

                $getStream | Select-Object -ExpandProperty 'values'
            }
        }
        else
        {
            if( $Method -eq [Microsoft.PowerShell.Commands.WebRequestMethod]::Get -or $PSCmdlet.ShouldProcess($uri,$method) )
            {
                Invoke-RestMethod -Method $Method -Uri $uri -Headers $headers -ContentType 'application/json' @bodyParam -ErrorVariable 'errors'
            }
        }
    }
    catch
    {
        $responseContent = $null
        $exceptionType = $_.Exception.GetType().FullName

        if ($exceptionType -eq 'System.Net.WebException')
        {
            $response = $_.Exception.Response
            if( $response )
            {
                $reader = New-Object 'IO.StreamReader' $response.GetResponseStream()
                $responseContent = $reader.ReadToEnd() | ConvertFrom-Json
                $reader.Dispose()
            }
        }
        elseif (($exceptionType -eq 'Microsoft.PowerShell.Commands.HttpResponseException') -and $_.ErrorDetails)
        {
            try
            {
                $responseContent = $_.ErrorDetails | ConvertFrom-Json
            }
            catch
            {
                $responseContent = $_.ErrorDetails
            }
        }

        for( $idx = 0; $idx -lt $errors.Count; ++$idx )
        {
            if( $Global:Error.Count -gt 0 )
            {
                $Global:Error.RemoveAt(0)
            }
        }

        if( -not $responseContent )
        {
            Write-Error -ErrorRecord $_ -ErrorAction $ErrorActionPreference
            return
        }

        foreach( $item in $responseContent.errors )
        {
            $message = $item.message
            if( $item.context )
            {
                $message ='{0} [context: {1}]' -f $message,$item.context
            }
            if( $item.exceptionName )
            {
                $message = '{0}: {1}' -f $item.exceptionName,$message
            }

            Write-Error -Message $message -ErrorAction $ErrorActionPreference
        }
    }
}


# Copyright 2016 - 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function Merge-BBServerPullRequest
{
    param(        
        [Parameter(Mandatory=$true)]
        [object]
        # An object that defines what Bitbucket Server to connect to and the credentials to use when connecting.
        $Connection,
        [Parameter(Mandatory=$true)]
        [string]
        # The key/ID that identifies the project where the repository will be created. This is *not* the project name.
        $ProjectKey,
        [Parameter(Mandatory=$true)]
        [string]
        # The name of a specific repository.
        $RepoName,
        [Parameter(Mandatory=$true)]
        [string]
        # this is the ID of the pull request you wish to merge, use the Get-BBServerPullRequest to find the ID
        $ID,
        [Parameter(Mandatory=$true)]
        [string]
        # this is to specify the current version of the pull request you wish to merge. you can get the version of the pull request from Get-BBServerPullRequest
        $Version
    )
    Set-StrictMode -Version 'Latest'
    Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState
    
    $Body = @{
        version = $Version;
    }
    $ResourcePath = ('projects/{0}/repos/{1}/pull-requests/{2}/merge' -f $ProjectKey, $RepoName, $ID )

    return $Body | Invoke-BBServerRestMethod -Connection $Connection -Method 'POST' -ApiName 'api' -ResourcePath $ResourcePath
}


# Copyright 2016 - 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function Move-BBServerRepository
{
    <#
    .SYNOPSIS
    Move a repository in Bitbucket Server from one project to another.
 
    .DESCRIPTION
    The `Move-BBServerRepository` moves a repository in Bitbucket Server.
 
    Use the `New-BBServerConnection` function to create a connection object to pass to the `Connection` parameter.
 
    .EXAMPLE
    Move-BBServerRepository -Connection $conn -ProjectKey 'BBSA' -RepoName 'fubarsnafu' -TargetProjectKey 'BBSA_NEW'
 
    Demonstrates how to move the repository 'fubarsnafu' from the 'BBSA' project to the 'BBSA_NEW'
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [object]
        # The connection information that describe what Bitbucket Server instance to connect to, what credentials to use, etc. Use the `New-BBServerConnection` function to create a connection object.
        $Connection,

        [Parameter(Mandatory=$true)]
        [string]
        # The key/ID that identifies the project where the repository currently resides. This is *not* the project name.
        $ProjectKey,

        [Parameter(Mandatory=$true)]
        [object]
        # The name of a specific repository to move to the new project.
        $RepoName,

        [Parameter(Mandatory=$true)]
        # The key/ID that identifies the target project where the repository will be moved. This is *not* the project name.
        $TargetProjectKey
    )
    
    Set-StrictMode -Version 'Latest'
    Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState

    $resourcePath = ('projects/{0}/repos/{1}' -f $ProjectKey, $RepoName)
    
    $getProjects = Get-BBServerProject -Connection $Connection

    $currentProject = $getProjects | Where-Object { $_.key -eq $ProjectKey }
    if( !$currentProject )
    {
        Write-Error -Message ('A project with key/ID ''{0}'' does not exist. Specified repository cannot be moved.' -f $ProjectKey)
        return
    }
    
    $targetProject = $getProjects | Where-Object { $_.key -eq $TargetProjectKey }
    if( !$targetProject )
    {
        Write-Error -Message ('A project with key/ID ''{0}'' does not exist. Specified repository cannot be moved.' -f $TargetProjectKey)
        return
    }
    
    $currentRepo = Get-BBServerRepository -Connection $Connection -ProjectKey $ProjectKey | Where-Object { $_.name -eq $RepoName }
    if( !$currentRepo )
    {
        Write-Error -Message ('A repository with name ''{0}'' does not exist in the project ''{1}''. Specified respository cannot be moved.' -f $RepoName, $ProjectKey)
        return
    }
        
    $repoProjectConfig = @{ project = @{ key = $TargetProjectKey } }
    $setRepoProject = Invoke-BBServerRestMethod -Connection $Connection -Method 'PUT' -ApiName 'api' -ResourcePath $resourcePath -InputObject $repoProjectConfig
    
    return $setRepoProject
}


# Copyright 2016 - 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function New-BBServerBranch
{
    <#
    .SYNOPSIS
    Creates a new branch in a repository.
 
    .DESCRIPTION
    The `New-BBServerBranch` function creates a new branch in a repository if it does not already exist. If the specified branch already exists, the function will do nothing.
     
    .EXAMPLE
    New-BBServerBranch -Connection $conn -ProjectKey 'TestProject' -RepoName 'TestRepo' -BranchName 'develop' -StartPoint 'master'
 
    Demonstrates how to create a branch named 'develop' in in the `TestRepo` repository. The new branch will start in the current state of the existing 'master' branch
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [object]
        # An object that defines what Bitbucket Server to connect to and the credentials to use when connecting.
        $Connection,

        [Parameter(Mandatory=$true)]
        [string]
        # The key/ID that identifies the project where the repository resides. This is *not* the project name.
        $ProjectKey,

        [Parameter(Mandatory=$true)]
        [string]
        # The name of a specific repository.
        $RepoName,

        [Parameter(Mandatory=$true)]
        [string]
        # The name of the branch to create.
        $BranchName,

        [Parameter(Mandatory=$true)]
        [string]
        # The existing branch name or hash id of the commit/changeset to use as the HEAD of the new branch.
        $StartPoint
    )
    
    Set-StrictMode -Version 'Latest'
    Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState
    
    $resourcePath = ('projects/{0}/repos/{1}/branches' -f $ProjectKey, $RepoName)
    
    $checkBranchExists = Get-BBServerBranch -Connection $Connection -ProjectKey $ProjectKey -RepoName $RepoName -BranchName $BranchName
    if( $checkBranchExists )
    {
        Write-Error -Message ('A branch with the name ''{0}'' already exists in the ''{1}'' repository. No new branch will be created.' -f $BranchName, $RepoName)
        return
    }

    $newBranchConfig = @{ name = $BranchName ; startPoint = $StartPoint }
    $newBranch = Invoke-BBServerRestMethod -Connection $Connection -Method 'POST' -ApiName 'api' -ResourcePath $resourcePath -InputObject $newBranchConfig

    return $newBranch
}


# Copyright 2016 - 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function New-BBServerConnection
{
    <#
    .SYNOPSIS
    Creates an object that represents a connection to an instance of Bitbucket Server.
 
    .DESCRIPTION
    The `New-BBServerConnection` function creates a connection object that is used by most Bitbucket Server Automation functions to connect to Bitbucket Server. You pass it credentials and the URI to the Bitbucket Server you want to connect to. It returns an object that is then passed to additional functions that require it.
 
    .EXAMPLE
    $conn = New-BBServerConnection -Credential (Get-Credential) -Uri 'https://bitbucketserver.example.com/'
 
    Demonstrates how to create a connection.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [pscredential]
        # The credential to use when connecting to Bitbucket Server. The credential is passed in plaintext, so make sure your Bitbucket Server connection is over HTTPS.
        $Credential,

        [Parameter(Mandatory=$true)]
        [uri]
        # The URI to the Bitbucket Server to connect to. The path to the API to use is appended to this URI. Typically, you'll just pass the protocol and hostname, e.g. `https://bitbucket.example.com`.
        $Uri,

        [string]
        # The version of the API to use. The default is `1.0`.
        $ApiVersion = '1.0'
    )

    Set-StrictMode -Version 'Latest'

    [pscustomobject]@{
                        'Credential' = $Credential;
                        'Uri' = $Uri;
                        'ApiVersion' = '1.0';
                     }
}

# Copyright 2019 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function New-BBServerDefaultReviewer
{
    <#
    .SYNOPSIS
    Creates a new default reviewer pull request condition for a project or repository.
 
    .DESCRIPTION
    The `New-BBServerDefaultReviewer` function creates a default reviewer pull request condition for a given project or repository. A new default reviewer condition is always created, even if an existing one with identical parameters exists.
 
    Pass Bitbucket Server user objects to the `User` parameter (use `Get-BBServerUser` to get user objects). Pass the number of required approvals to the `ApprovalCount` parameter (must be less than or equal to number of `User`).
 
    By default, the default reviewer condition will be created at the project level with a Source and Target branch of "Any". To create a default reviewer condition for a repository, pass the name of a repository to the `RepositoryName` parameter.
 
    When `SourceBranchType`/`TargetBranchType` is `Model`, the `SourceBranchValue`/`TargetBranchValue` parameter argument **must** be one of: `Feature`, `Bugfix`, `Hotfix`, `Release`, `Development`, `Production`
 
    .EXAMPLE
    New-BBServerDefaultReviewer -Connection $conn -ProjectKey 'NBBSDR' -User (Get-BBServerUser -Connection $conn -Filter 'samiam@example.com') -ApprovalCount 1
 
    Demonstrates creating a new default reviewer pull request condition for user with email "samiam@example.com" and required approval count of `1`. The source and target matching branches will be default of `Any`.
 
    .EXAMPLE
    New-BBServerDefaultReviewer -Connection $conn -ProjectKey 'NBBSDR' -User $requiredReviewers -ApprovalCount 3 -TargetBranchType 'Name' -TargetBranchValue 'master'
 
    Demonstrates creating a new default reviewer condition for a collection of users and required approval count of `3` for any pull request that targets the `master` branch.
 
    .EXAMPLE
    New-BBServerDefaultReviewer -Connection $conn -ProjectKey 'NBBSDR' -User $requiredReviewers -ApprovalCount 0 -SourceBranchType 'Pattern' -SourceBranchValue 'feature/*' -TargetBranchType 'Model' -TargetBranchValue 'Development'
 
    Demonstrates creating a new default reviewer condition for a collection of users and require no approvals for any pull request that comes from a `feature/*` branch and targets the `Development` model branch configured for a repository.
 
    .EXAMPLE
    New-BBServerDefaultReviewer -Connection $conn -ProjectKey 'NBBSDR' -User $requiredReviewers -ApprovalCount 3 -RepositoryName 'Web Service Application' -TargetBranchType 'Name' -TargetBranchValue 'master'
 
    Demonstrates creating a new default reviewer condition for a collection of users and required approval count of `3` for any pull request that targets the `master` branch in the repository named "Web Service Application".
    #>

    param(
        [Parameter(Mandatory)]
        [object]
        # An object that defines what Bitbucket Server to connect to and the credentials to use when connecting. Use `New-BBServerConnection` to create connection objects.
        $Connection,

        [Parameter(Mandatory)]
        [string]
        # The key/ID that identifies the project. This is *not* the project name.
        $ProjectKey,

        [Parameter(Mandatory)]
        [object[]]
        # Collection of objects representing the users to add to the default reviewer condition. Use `Get-BBServerUser` to get Bitbucket Server user objects.
        $User,

        [Parameter(Mandatory)]
        [int]
        # The number of default reviewers that must approve a pull request.
        $ApprovalCount,

        [ValidateSet('Any', 'Name', 'Pattern', 'Model')]
        # The type of matching for the source branch.
        $SourceBranchType = 'Any',

        [string]
        # Specifies the value or pattern to match a source branch, if `-SourceBranchType` is not "Any".
        $SourceBranchValue,

        [ValidateSet('Any', 'Name', 'Pattern', 'Model')]
        # The type of matching for the target branch.
        $TargetBranchType = 'Any',

        [string]
        # Specifies the value or pattern to match a target branch, if `-TargetBranchType` is not "Any".
        $TargetBranchValue,

        [string]
        # The name of a repository in the project.
        $RepositoryName
    )

    Set-StrictMode -Version 'Latest'
    Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState

    $sourceMatcherConfig = Get-DefaultReviewerBranchMatcher -TypeParameterName 'SourceBranchType' -ValueParameterName 'SourceBranchValue' -Type $SourceBranchType -Value $SourceBranchValue
    if (-not $sourceMatcherConfig)
    {
        return
    }

    $targetMatcherConfig = Get-DefaultReviewerBranchMatcher -TypeParameterName 'TargetBranchType' -ValueParameterName 'TargetBranchValue' -Type $TargetBranchType -Value $TargetBranchValue
    if (-not $targetMatcherConfig)
    {
        return
    }

    $userCount = $User | Measure-Object | Select-Object -ExpandProperty 'Count'
    if ($ApprovalCount -gt $userCount)
    {
        Write-Error -Message ('"ApprovalCount" ({0}) must be less than or equal to the number of users passed to the "User" parameter ({1}).' -f $ApprovalCount, $userCount) -ErrorAction $ErrorActionPreference
        return
    }

    $idx = -1
    $userProperties = @('name', 'emailAddress', 'id', 'displayName', 'active', 'slug', 'type')
    foreach ($userObj in $User)
    {
        $idx++
        foreach ($property in $userProperties)
        {
            if (-not ($userObj | Get-Member -Name $property))
            {
                Write-Error -Message ('User[{0}] doesn''t have a "{1}" property. Make sure you''re using the "Get-BBServerUser" function to get users.' -f $idx, $property) -ErrorAction $ErrorActionPreference
                return
            }
        }
    }

    $requestBody = @{
        reviewers = @($User | Select-Object -Property $userProperties)
        sourceMatcher = $sourceMatcherConfig
        targetMatcher = $targetMatcherConfig
        requiredApprovals = $ApprovalCount
    }

    $resourcePath = 'projects/{0}' -f $ProjectKey
    if ($RepositoryName)
    {
        $resourcePath = '{0}/repos/{1}' -f $resourcePath,$RepositoryName
    }
    $resourcePath = '{0}/condition' -f $resourcePath

    $requestBody | Invoke-BBServerRestMethod -Connection $Connection -Method Post -ApiName 'default-reviewers' -ResourcePath $resourcePath
}


# Copyright 2016 - 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function New-BBServerProject
{
    <#
    .SYNOPSIS
    Creates a new project.
 
    .DESCRIPTION
    The `New-BBServerProject` function creates a new Bitbucket Server projects. All repositories in Bitbucket Server must be part of a project. Projects are used to group like repositories together.
 
    Typically, source control repositories should be organized around your code and software, not your teams and organizations. Teams and organizations change more frequently than the technology and purpose of software, so organizing by your code leads to a more stable structure.
 
    .LINK
    https://confluence.atlassian.com/bitbucket/projects-792497956.html
 
    .EXAMPLE
    New-BBServerProject -Connection $conn -Key 'FBR' -Name 'Fubar Snafu'
 
    Demonstrates how to create a Bitbucket Server project. In this case a new project with key `FBR` and name `Fubar Snafu` will be created in the Bitbucket Server instance represented in the `$conn` object.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [object]
        # An object that defines what Bitbucket Server to connect to and the credentials to use when connecting. Use `New-BBServerConnection` to create connection objects.
        $Connection,

        [Parameter(Mandatory=$true)]
        [ValidatePattern('^[A-Za-z][A-Za-z0-9_]+$')]
        [ValidateLength(1,128)]
        [string]
        # A unique identifier for the project. Keys must begin with a letter and contain only letters, numbers, or underscore (e.g. `_`). It must be less than 128 characters.
        $Key,

        [Parameter(Mandatory=$true)]
        [string]
        # The name of the project.
        $Name,

        [string]
        # A description of the project.
        $Description
    )
    
    Set-StrictMode -Version 'Latest'
    Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState

    $request = @{
                    key = $Key;
                    name = $Name;
                    description = $Description;
                } 
    $project = $request | Invoke-BBServerRestMethod -Connection $Connection -Method Post -ApiName 'api' -ResourcePath 'projects' | Add-PSTypeName -ProjectInfo
    if( -not $project )
    {
        return
    }

    return $project
}

# Copyright 2016 - 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function New-BBServerPullRequest 
{
    param(        
        [Parameter(Mandatory=$true)]
        [object]
        # An object that defines what Bitbucket Server to connect to and the credentials to use when connecting.
        $Connection,
        [Parameter(Mandatory=$true)]
        [string]
        # The key/ID that identifies the project where the repository will be created. This is *not* the project name.
        $ProjectKey,
        [Parameter(Mandatory=$true)]
        [string]
        # The name of a specific repository.
        $RepoName,
        [Parameter(Mandatory=$true)]
        [string]
        # The name of the branch that you wish to merge from
        $From,
        [Parameter(Mandatory=$true)]
        [string]
        # The name of destination branch
        $To,
        [Parameter(Mandatory=$true)]
        [string]
        # The title of the pull request you wish to create, this cannot be blank.
        $Title
    )
    Set-StrictMode -Version 'Latest'
    Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
    $Body = @{
        title = $Title;
        state = 'OPEN';
        open = $true;
        closed = $false;
        fromRef = @{
            id = $From;
            repository = @{
                slug = $RepoName;
                name = $null;
                project = @{
                    key = $ProjectKey
                };
            };
        };
        toRef = @{
            id = $To;
            repository = @{
                slug = $RepoName;
                name = $null;
                project = @{
                    key = $ProjectKey
                };
            };
        };
        locked = $false;
        reviewers = $null;
        links = @{
            self = @();
        };
    };
    $ResourcePath = ('projects/{0}/repos/{1}/pull-requests' -f $ProjectKey, $RepoName)

    return $Body | Invoke-BBServerRestMethod -Connection $Connection -Method 'POST' -ApiName 'api' -ResourcePath $ResourcePath
}


# Copyright 2016 - 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function New-BBServerRepository
{
    <#
    .SYNOPSIS
    Creates a new repository in Bitbucket Server.
 
    .DESCRIPTION
    The `New-BBServerRepository` function creates a new Git repository in Bitbucket Server. It requires an project to exist where the repository should exist (all repositories in Bitbucket Server are part of a project).
 
    By default, the repository is setup to allow forking and be private. To disable forking, use the `NotForkable` switch. To make the repository public, use the `Public` switch.
 
    Use the `New-BBServerConnection` function to generate the connection object that should get passed to the `Connection` parameter.
 
    .EXAMPLE
    New-BBServerRepository -Connection $conn -ProjectKey 'BBSA' -Name 'fubarsnafu'
 
    Demonstrates how to create a repository.
 
    .EXAMPLE
    New-BBServerRepository -Connection $conn -ProjectKey 'BBSA' -Name 'fubarsnafu' -NotForkable -Public
 
    Demonstrates how to create a repository with different default settings. The repository will be not be forkable and will be public, not private.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [object]
        # The connection information that describe what Bitbucket Server instance to connect to, what credentials to use, etc. Use the `New-BBServerConnection` function to create a connection object.
        $Connection,

        [Parameter(Mandatory=$true)]
        [string]
        # The key/ID that identifies the project where the repository will be created. This is *not* the project name.
        $ProjectKey,

        [Parameter(Mandatory=$true)]
        [ValidateLength(1,128)]
        [string]
        # The name of the repository to create.
        $Name,

        [Switch]
        # Disable the ability to fork the repository. The default is to allow forking.
        $NotForkable,

        [Switch]
        # Make the repository public. Not sure what that means.
        $Public
    )

    Set-StrictMode -Version 'Latest'
    Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState

    $forkable = $true
    if( $NotForkable )
    {
        $forkable = $false
    }

    $newRepoInfo = @{
                        name = $Name;
                        scmId = 'git';
                        forkable = $forkable;
                        public = [bool]$Public;
                    }

    $repo = $newRepoInfo | Invoke-BBServerRestMethod -Connection $Connection -Method Post -ApiName 'api' -ResourcePath ('projects/{0}/repos' -f $ProjectKey)
    if( $repo )
    {
        $repo | Add-PSTypeName -RepositoryInfo
    }
}

# Copyright 2016 - 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function New-BBServerTag
{
    <#
    .SYNOPSIS
    Creates a new Version Tag on a commit in Bitbucket Server.
 
    .DESCRIPTION
    The `New-BBServerTag` function creates a new Git Tag with Version information on a commit in Bitbucket Server. It requires a commit to exist in a repository, and a project to exist where the repository should live (all repositories in Bitbucket Server are part of a project).
 
    By default, the tag will be lightweight and will not contain a tag message. However, those properties can both be overridden with their respective parameters. To add a message to the Tag, utilize the $Message parameter, and if you would prefer to use an annotated tag, use the parameter $Type = 'ANNOTATED'
 
    Use the `New-BBServerConnection` function to generate the connection object, `New-BBServerRepository` to generate the repository object, and `New-BBServerProject` to generate the project, which should be passed in as the `$Connection`, `$RepositoryKey`, and `$ProjectKey` parameters.
 
    The `$Force` parameter will allow the user to force the tag to be generated for that commit regardless of the tags use on other commits in the repo.
 
    .EXAMPLE
    New-BBServerTag -Connection $conn -ProjectKey $key -RepositoryKey $repoName -name $TagName -CommitID $commitHash
 
    Demonstrates the default behavior of tagging a commit with a version tag.
 
    .EXAMPLE
    New-BBServerTag -Connection $conn -ProjectKey $key -RepositoryKey $repoName -name $TagName -CommitID $commitHash -Message 'Tag Message' -Force -Type 'ANNOTATED'
 
    Demonstrates how to tag a commit with an annotated tag containing a tag message with the force parameter enabled.
    #>


    [CmdletBinding()]
    param(
 
        [Parameter(Mandatory=$true)]
        [object]
        # An object that defines what Bitbucket Server to connect to and the credentials to use when connecting.
        $Connection,    
 
        [Parameter(Mandatory=$true)]
        [string]
        # The key of the repository's project.
        $ProjectKey,
 
        [Parameter(Mandatory=$true)]
        [string]
        # The key of the repository.
        $RepositoryKey,
 
        [Parameter(Mandatory=$true)]
        [string]
        # The tag's name/value.
        $Name,
 
        [Parameter(Mandatory=$true)]
        [string]
        # The commit ID the tag should point to. In the Bitbucket Server API documentation, this is called the `startPoint`.
        $CommitID,
 
        [string]
        # An optional message for the commit that creates the tag.
        $Message = "",

        [Switch]
        $Force,

        [String]
        $Type = "LIGHTWEIGHT"
 
    )
 
    Set-StrictMode -Version 'Latest'
    Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState

    $tag = @{
                name = $Name
                startPoint = $CommitID
                message = $Message
                type = $Type
                }
    if( $Force )
    {
        $tag['force'] = "true"
    }

    $result = $tag | Invoke-BBServerRestMethod -Connection $Connection -Method Post -ApiName 'git' -ResourcePath ('projects/{0}/repos/{1}/tags' -f $ProjectKey, $RepositoryKey)
    if (-not $result)
    {
        Write-Error ("Unable to tag commit {0} with {1}." -f $CommitID, $Name)
    }
}
 

# Copyright 2016 - 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function Remove-BBServerRepository
{
    <#
    .SYNOPSIS
    Remove a repository from Bitbucket Server.
 
    .DESCRIPTION
    The `Remove-BBServerRepository` deletes a repository from Bitbucket Server. This is a dangerous operation as all related data is also deleted. You will have to confirm the deletion. To force the deletion without being confirmed, use the `Force` switch.
 
    Use the `New-BBServerConnection` function to create a connection object to pass to the `Connection` parameter.
 
    .EXAMPLE
    Remove-BBServerRepository -Connection $conn -ProjectKey 'BBSA' -Name 'fubarsnafu'
 
    Demonstrates how to delete a repository. Because deleting a repository is a high-impact operation, you will asked to confirm the deletion.
 
    .EXAMPLE
    Remove-BBServerRepository -Connection $conn -ProjectKey 'BBSA' -Name 'fubarsnafu' -Force
 
    Demonstrates how to delete a repository, skipping any confirmation dialogs. This can be dangerous since deletions can't be undone. Use the `Force` switch with care.
 
    .EXAMPLE
    Get-BBServerRepository -Connection $conn -ProjectKey 'BBSA' -Name 'snafu' | Remove-BBServerRepository -Connection $conn
 
    Demonstrates that you can pipe objects returned by `Get-BBServerRepository` to `Remove-BBServerRepository`. When you pipe repository objects, you don't have to provide the project key
 
    .EXAMPLE
    'fubarsnafu' | Remove-BBServerRepository -Connection $conn -ProjectKey 'BBSA'
 
    Demonstrates that you can pipe repository names to `Remove-BBServerRepository`. When you do, you *must* also provide the project key.
    #>

    [CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact="High")]
    param(
        [Parameter(Mandatory=$true)]
        [object]
        # The connection information that describe what Bitbucket Server instance to connect to, what credentials to use, etc. Use the `New-BBServerConnection` function to create a connection object.
        $Connection,

        [string]
        # The key/ID that identifies the project where the repository will be created. This is *not* the project name.
        $ProjectKey,

        [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
        [object]
        # The name of a specific repository to get.
        $Name,

        [Switch]
        # Don't prompt the user to confirm the deletion of the repository. This is a dangerous switch to use, since repository deletions can't be undone.
        $Force
    )

    process 
    {
        Set-StrictMode -Version 'Latest'
        Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState
    
        if( $Name.pstypenames -contains 'Atlassian.Bitbucket.Server.RepositoryInfo' )
        {
            $repoInfo = $Name
            $Name = $repoInfo.name
            if( -not $Name )
            {
                Write-Error -Message ('Repository name not found. Looks like you piped in an invalid repository object because either we can''t find the `name` property or it doesn''t have a value.')
                return
            }

            $ProjectKey = $repoInfo.project.key
            if( -not $ProjectKey )
            {
                Write-Error -Message ('Project key not found. Looks like you piped in an invalid repository object becuse either the `project.key` properties don''t exist or they don''t have values.')
                return
            }
        }

        if( -not $ProjectKey )
        {
            Write-Error -Message ('ProjectKey parameter missing. When passing the name of a repository with the Name parameter you must also pass the repository''s project key with the ProjectKey parameter.')
            return
        }

        $whatIfMessage = 'removing repository ''{0}/{1}'' from {2}' -f $ProjectKey,$Name,$Connection.Uri
        $confirmMessage = 'Do you want to remove repository ''{0}/{1}'' from {2}?{3}{3}This operation is PERMANENT and can''t be undone!' -f $ProjectKey,$Name,$Connection.Uri,[Environment]::NewLine
        if( $Force -or $PSCmdlet.ShouldProcess($whatIfMessage,$confirmMessage,'Confirm Permanently Deleting Repository') )
        {
            $result = Invoke-BBServerRestMethod -Connection $Connection -Method Delete -ApiName 'api' -ResourcePath ('projects/{0}/repos/{1}' -f $projectKey,$Name)
        
            if( $result )
            {
                $result | ConvertTo-Json | Write-Verbose
            }
        }
    }
}


# Copyright 2016 - 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function Remove-BBServerTag 
{
    <#
    .SYNOPSIS
    Removes specified tags from a repository in Bitbucket Server.
 
    .DESCRIPTION
    The `Remove-BBServerTag` function takes an array of git tags and removes them from the specified Bitbucket Server repository. If any of the requested tags do not exist on the server, an error is thrown.
 
    .EXAMPLE
    Remove-BBServerTag -Connection $conn -ProjectKey $key -RepositoryKey $repoName -TagName $tag.displayId
 
    Demonstrates how to remove the git tag for the associated repo
    #>

    param(
        [Parameter(Mandatory=$true)]
        # An object that defines what Bitbucket Server to connect to and the credentials to use when connecting.
        [object]$Connection,    
  
        [Parameter(Mandatory=$true)]
        # The key of the repository's project.
        [String]$ProjectKey,
 
        [Parameter(Mandatory=$true)]
        # The key of the repository.
        [String]$RepositoryKey,

        [Parameter(Mandatory=$true)]
        # The name of the tag to be deleted.
        [String[]]$TagName
    )
  
    Set-StrictMode -Version 'Latest'
    Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState

    foreach( $tag in $TagName )
    {
        Invoke-BBServerRestMethod -Connection $Connection -Method DELETE -ApiName 'git' -ResourcePath ('projects/{0}/repos/{1}/tags/{2}' -f $ProjectKey, $RepositoryKey, $tag) 
    }
}

 


# Copyright 2016 - 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function Rename-BBServerRepository
{
    <#
    .SYNOPSIS
    Rename a repository in Bitbucket Server.
 
    .DESCRIPTION
    The `Rename-BBServerRepository` renames a repository in Bitbucket Server.
 
    Use the `New-BBServerConnection` function to create a connection object to pass to the `Connection` parameter.
 
    .EXAMPLE
    Rename-BBServerRepository -Connection $conn -ProjectKey 'BBSA' -RepoName 'fubarsnafu' -TargetRepoName 'snafu_fubar'
 
    Demonstrates how to rename a repository from 'fubarsnafu' to 'snafu_fubar'.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [object]
        # The connection information that describe what Bitbucket Server instance to connect to, what credentials to use, etc. Use the `New-BBServerConnection` function to create a connection object.
        $Connection,

        [Parameter(Mandatory=$true)]
        [string]
        # The key/ID that identifies the project where the repository currently resides. This is *not* the project name.
        $ProjectKey,

        [Parameter(Mandatory=$true)]
        [object]
        # The name of a specific repository to rename.
        $RepoName,

        [Parameter(Mandatory=$true)]
        # The target name that the repository will be renamed to.
        $TargetRepoName
    )
    
    Set-StrictMode -Version 'Latest'
    Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState

    $resourcePath = ('projects/{0}/repos/{1}' -f $ProjectKey, $RepoName)
    
    $getRepos = Get-BBServerRepository -Connection $Connection -ProjectKey $ProjectKey
    
    $currentRepo = $getRepos | Where-Object { $_.name -eq $RepoName }
    if( !$currentRepo )
    {
        Write-Error -Message ('A repository with name ''{0}'' does not exist in the project ''{1}''. Specified respository cannot be renamed.' -f $RepoName, $ProjectKey)
        return
    }
    
    $targetRepo = $getRepos | Where-Object { $_.name -eq $TargetRepoName }
    if( $targetRepo )
    {
        Write-Error -Message ('A repository with name ''{0}'' already exists in the project ''{1}''. Specified respository cannot be renamed.' -f $TargetRepoName, $ProjectKey)
        return
    }
        
    $repoRenameConfig = @{ name = $TargetRepoName }
    $setRepoName = Invoke-BBServerRestMethod -Connection $Connection -Method 'PUT' -ApiName 'api' -ResourcePath $resourcePath -InputObject $repoRenameConfig
    
    return $setRepoName
}


# Copyright 2016 - 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function Set-BBServerCommitBuildStatus
{
    <#
    .SYNOPSIS
    Sets the build status of a commit in Bitbucket Server.
 
    .DESCRIPTION
    The `Set-BBServerCommitBuildStatus` function sets the build status of a specific commit in Bitbucket Server. The status can be in progress, successful, or failed. When a build status is set, Bitbucket Server will show a blue "in progress" icon for in progress builds, a green checkmark icon for successful builds, and a red failed icon for failed builds.
 
    Data about the commit is read from the environment set up by supported build servers, which is Jenkins. Bitbucket Server must have the commit ID, a key that uniquely identifies this specific build, and a URI that points to the build's report. The build name is optional, but when running under a supported build server, is also pulled from the environment.
 
    If a commit already has a status, this function will overwrite it.
 
    .EXAMPLE
    Set-BBServerCommitBuildStatus -Connection $conn -Status InProgress
 
    Demonstrates how this function should be called when running under a build server. Currently, Jenkins and TeamCity are supported.
 
    .EXAMPLE
    Set-BBServerCommitBuildStatus -Connection $conn -Status Successful -CommitID 'e24e50bba38db28fb8cf433d00c0d3372f8405cf' -Key 'jenkins-BitbucketServerAutomation-140' -BuildUri 'https://jenkins.example.com/job/BitbucketServerAutomation/140/' -Name 'BitbucketServerAutomation'
 
    Demonstrates how to set the build status for a commit using your own custom commit ID, key, and build URI.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [object]
        # The connection to the Bitbucket Server. Use `New-BBServerConnection` to create one.
        $Connection,

        [Parameter(Mandatory=$true)]
        [ValidateSet('InProgress','Successful','Failed')]
        # The status of the build.
        $Status,

        [ValidateLength(1,255)]
        [string]
        # The ID of the commit. The default value is read from environment variables set by build servers.
        #
        # If running under Jenkins, the `GIT_COMMIT` environment variable is used.
        #
        # If not running under a build server, and none of the above environment variables are set, this function write an error and does nothing.
        $CommitID,

        [ValidateLength(1,255)]
        [string]
        # A value that uniquely identifies the build. The default value is pulled from environment variables that get set by build servers.
        #
        # If running under Jenkins the `BUILD_TAG` environment variable is used.
        #
        # If not running under a build server, and none of the above environment variables are set, this function write an error and does nothing.
        $Key,

        [ValidateScript({ $_.ToString().Length -lt 450 })]
        [uri]
        # A URI to the build results. The default is read from the environment variables that get set by build servers.
        #
        # If running under Jenkins, the `BUILD_URL` environment variable is used.
        #
        # If not running under a build server, and none of the above environment variables are set, this function write an error and does nothing.
        $BuildUri,

        [ValidateLength(1,255)]
        [string]
        # The name of the build. The default value is read from environment variables that get set by build servers.
        #
        # If running under Jenkins, the `JOB_NAME` environment variable is used.
        #
        # If not running under a build server, and none of the above environment variables are set, this function write an error and does nothing.
        $Name,

        [string]
        [ValidateLength(1,255)]
        # A description of the build. Useful if the state is failed. Default is an empty string.
        $Description = ''
    )

    Set-StrictMode -Version 'Latest'
    Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState

    # We're in Jenkins
    $body = @{
                state = $Status.ToUpperInvariant();
                description = $Description;
             }
    if( (Test-Path -Path 'env:JENKINS_URL') )
    {
        $body.key = (Get-Item -Path 'env:BUILD_TAG').Value;
        $body.name = (Get-Item -Path 'env:JOB_NAME').Value;
        $body.url = (Get-Item -Path 'env:BUILD_URL').Value;
        if( -not $CommitID )
        {
            $CommitID = (Get-Item -Path 'env:GIT_COMMIT').Value
        }
    }

    if( $PSBoundParameters.ContainsKey('Key') )
    {
        $body['key'] = $Key
    }

    if( $PSBoundParameters.ContainsKey('BuildUri') )
    {
        $body['url'] = $BuildUri
    }

    if( $PSBoundParameters.ContainsKey('Name') )
    {
        $body['name'] = $Name
    }

    $resourcePath = 'commits/{0}' -f $CommitID

    Write-Verbose -Message ('Setting ''{0}'' commit''s build status to ''{1}''.' -f $CommitID,$body.state)
    $body | Invoke-BBServerRestMethod -Connection $Connection -Method Post -ApiName 'build-status' -ResourcePath $resourcePath
}


# Copyright 2016 - 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function Set-BBServerDefaultBranch
{
    <#
    .SYNOPSIS
    Sets the default branch in a repository.
 
    .DESCRIPTION
    The `Set-BBServerDefaultBranch` function sets the specified branch as the default branch in a repository.
     
    .EXAMPLE
    Set-BBServerDefaultBranch -Connection $conn -ProjectKey 'TestProject' -RepoName 'TestRepo' -BranchName 'develop'
 
    Demonstrates how to set the branch named 'develop' as the default branch in the `TestRepo` repository.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [object]
        # An object that defines what Bitbucket Server to connect to and the credentials to use when connecting.
        $Connection,

        [Parameter(Mandatory=$true)]
        [string]
        # The key/ID that identifies the project where the repository resides. This is *not* the project name.
        $ProjectKey,

        [Parameter(Mandatory=$true)]
        [string]
        # The name of a specific repository.
        $RepoName,

        [Parameter(Mandatory=$true)]
        [string]
        # The name of the branch to configure as the default branch.
        $BranchName
    )
    
    Set-StrictMode -Version 'Latest'
    Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState
    
    $resourcePath = ('projects/{0}/repos/{1}/branches/default' -f $ProjectKey, $RepoName)
    
    $getCurrentBranch = Get-BBServerBranch -Connection $Connection -ProjectKey $ProjectKey -RepoName $RepoName -BranchName $BranchName
    if( !$getCurrentBranch )
    {
        Write-Error -Message ('A branch with the name ''{0}'' does not exist in the ''{1}'' repository and cannot be set as the default. Use the `New-BBServerBranch` function to create new branches.' -f $BranchName, $RepoName)
        return
    }
    
    $defaultBranchConfig = @{ id = $getCurrentBranch.id }
    $setDefaultBranch = Invoke-BBServerRestMethod -Connection $Connection -Method 'PUT' -ApiName 'api' -ResourcePath $resourcePath -InputObject $defaultBranchConfig
    
    $getCurrentBranch = Get-BBServerBranch -Connection $Connection -ProjectKey $ProjectKey -RepoName $RepoName -BranchName $BranchName
    return $getCurrentBranch
}


# Copyright 2019 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function Set-BBServerDefaultReviewer
{
    <#
    .SYNOPSIS
    Updates an existing default reviewer pull request condition for a given project or repository.
 
    .DESCRIPTION
    The `Set-BBServerDefaultReviewer` function updates the configuration of an existing default reviewer pull request condition for a project or repository. Only the condition parameters you pass to this function will be updated in the existing default reviewer condition, the rest of the parameters in the condition are left as-is.
 
    You must pass the `ID` of an existing default reviewer condition to this function (use `Get-BBServerDefaultReviewer` to get existing default reviewer conditions). If updating a default reviewer condition for a repository, you must also pass the name of the repository to the `RepositoryName` parameter.
 
    Pass Bitbucket Server user objects to the `User` parameter (use `Get-BBServerUser` to get user objects). Pass the number of required approvals to the `ApprovalCount` parameter (must be less than or equal to number of given `User` or the existing users configured in the condition).
 
    When `SourceBranchType`/`TargetBranchType` is `Model`, the `SourceBranchValue`/`TargetBranchValue` parameter argument **must** be one of: `Feature`, `Bugfix`, `Hotfix`, `Release`, `Development`, `Production`
 
    .EXAMPLE
    Set-BBServerDefaultReviewer -Connection $conn -ProjectKey 'SBBSDR' -ID $existingCondition.id -ApprovalCount 2
 
    Demonstrates updating an existing default reviewer pull request condition to have a requried approval count of `2`.
 
    .EXAMPLE
    Set-BBServerDefaultReviewer -Connection $conn -ProjectKey 'SBBSDR' -ID $existingCondition.id -User (Get-BBServerUser -Connection $conn -Filter 'admin') -ApprovalCount 1
 
    Demonstrates updating an existing default reviewer pull request condition to only have the `admin` user and a required approval count of `1`.
 
    .EXAMPLE
    Set-BBServerDefaultReviewer -Connection $conn -ProjectKey 'SBBSDR' -ID $existingCondition.id -SourceBranchType 'Any' -TargetBranchType 'Name' -TargetBranchValue 'master'
 
    Demonstrates updating an existing default reviewer condition to apply to any pull request that targets the `master` branch.
 
    .EXAMPLE
    Set-BBServerDefaultReviewer -Connection $conn -ProjectKey 'SBBSDR' -ID $existingCondition.id -SourceBranchType 'Pattern' -SourceBranchValue 'hotfix/*' -TargetBranchType 'Model' -TargetBranchValue 'Production'
 
    Demonstrates updating an existing default reviewer condition to apply to any pull request that originates on a branch matching the pattern `hotfix/*` and targets the configured `Production` model branch.
    #>

    param(
        [Parameter(Mandatory)]
        [object]
        # An object that defines what Bitbucket Server to connect to and the credentials to use when connecting. Use `New-BBServerConnection` to create connection objects.
        $Connection,

        [Parameter(Mandatory)]
        [string]
        # The key/ID that identifies the project. This is *not* the project name.
        $ProjectKey,

        [Parameter(Mandatory)]
        [int]
        # The ID of the default reviewer condition. Use `Get-BBServerDefaultReviewer` to get the ID of an existing condition.
        $ID,

        [int]
        # The number of default reviewers that must approve a pull request.
        $ApprovalCount,

        [string]
        # The name of a repository in the project.
        $RepositoryName,

        [ValidateSet('Any', 'Name', 'Pattern', 'Model')]
        # The type of matching to do against the source branch.
        $SourceBranchType,

        [string]
        # Specifies the value or pattern to match a source branch, if `-SourceBranchType` is not "Any".
        $SourceBranchValue,

        [ValidateSet('Any', 'Name', 'Pattern', 'Model')]
        # The type of matching to do against the target branch.
        $TargetBranchType,

        [string]
        # Specifies the value or pattern to match a target branch, if `-TargetBranchType` is not "Any".
        $TargetBranchValue,

        [object[]]
        # Collection of objects representing the users to add to the default reviewer condition. Use `Get-BBServerUser` to get Bitbucket Server user objects.
        $User
    )

    Set-StrictMode -Version 'Latest'
    Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState

    if ($SourceBranchValue -and -not $SourceBranchType)
    {
        Write-Error -Message 'You must specify a "SourceBranchType" when giving a "SourceBranchValue".'
        return
    }

    if ($TargetBranchValue -and -not $TargetBranchType)
    {
        Write-Error -Message 'You must specify a "TargetBranchType" when giving a "TargetBranchValue".'
        return
    }

    $idx = -1
    $userProperties = @('name', 'emailAddress', 'id', 'displayName', 'active', 'slug', 'type')
    foreach ($userObj in $User)
    {
        $idx++
        foreach ($property in $userProperties)
        {
            if (-not ($userObj | Get-Member -Name $property))
            {
                Write-Error -Message ('User[{0}] doesn''t have a "{1}" property. Make sure you''re using the "Get-BBServerUser" function to get users.' -f $idx, $property) -ErrorAction $ErrorActionPreference
                return
            }
        }
    }

    $notFoundErrorMessageSuffix = 'project "{0}"' -f $ProjectKey
    $repositoryParam = @{ }
    if ($RepositoryName)
    {
        $notFoundErrorMessageSuffix = 'repository "{0}" in {1}' -f $RepositoryName, $notFoundErrorMessageSuffix
        $repositoryParam['RepositoryName'] = $RepositoryName
    }

    $existingCondition =
        Get-BBServerDefaultReviewer -Connection $Connection -ProjectKey $ProjectKey @repositoryParam |
        Where-Object { $_ } |
        Where-Object { $_.id -eq $ID }

    if (-not $existingCondition)
    {
        Write-Error -Message ('Default reviewer pull request condition with ID "{0}" does not exist for {1}.' -f $ID, $notFoundErrorMessageSuffix) -ErrorAction $ErrorActionPreference
        return
    }

    $requestBody = [PSCustomObject]@{
        reviewers = @($existingCondition.reviewers | Select-Object -Property $userProperties)
        sourceMatcher = $existingCondition.sourceRefMatcher
        targetMatcher = $existingCondition.targetRefMatcher
        requiredApprovals = $existingCondition.requiredApprovals
    }

    if ($PSBoundParameters.ContainsKey('ApprovalCount'))
    {
        $userCount = $requestBody.reviewers | Measure-Object | Select-Object -ExpandProperty 'Count'
        $tooManyUsersErrorSuffix = 'configured for the condition ({0})' -f $userCount
        if ($User)
        {
            $userCount = $User | Measure-Object | Select-Object -ExpandProperty 'Count'
            $tooManyUsersErrorSuffix = 'passed to the "User" parameter ({0})' -f $userCount
        }

        if ($ApprovalCount -gt $userCount)
        {
            Write-Error -Message ('"ApprovalCount" ({0}) must be less than or equal to the number of users {1}.' -f $ApprovalCount, $tooManyUsersErrorSuffix) -ErrorAction $ErrorActionPreference
            return
        }

        $requestBody.requiredApprovals = $ApprovalCount
    }

    if ($SourceBranchType)
    {
        $sourceMatcherConfig = Get-DefaultReviewerBranchMatcher -TypeParameterName 'SourceBranchType' -ValueParameterName 'SourceBranchValue' -Type $SourceBranchType -Value $SourceBranchValue
        if (-not $sourceMatcherConfig)
        {
            return
        }

        $requestBody.sourceMatcher = $sourceMatcherConfig
    }

    if ($TargetBranchType)
    {
        $targetMatcherConfig = Get-DefaultReviewerBranchMatcher -TypeParameterName 'TargetBranchType' -ValueParameterName 'TargetBranchValue' -Type $TargetBranchType -Value $TargetBranchValue
        if (-not $targetMatcherConfig)
        {
            return
        }

        $requestBody.targetMatcher = $targetMatcherConfig
    }

    if ($User)
    {
        $requestBody.reviewers = @($User | Select-Object -Property $userProperties)
    }

    $resourcePath = 'projects/{0}' -f $ProjectKey
    if ($RepositoryName)
    {
        $resourcePath = '{0}/repos/{1}' -f $resourcePath,$RepositoryName
    }
    $resourcePath = '{0}/condition/{1}' -f $resourcePath, $ID

    $requestBody | Invoke-BBServerRestMethod -Connection $Connection -Method Put -ApiName 'default-reviewers' -ResourcePath $resourcePath
}


# Copyright 2016 - 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function Set-BBServerPullRequestSetting
{
    <#
    .SYNOPSIS
    Sets the pull request settings for a repository.
 
    .DESCRIPTION
    The `Set-BBServerPullRequestSetting` function sets the specified pull request settings for a Bitbucket Server repository.
     
    .EXAMPLE
    Set-BBServerPullRequestSetting -Connection $conn -ProjectKey 'TestProject' -RepoName 'TestRepo' -RequiredApprovers 2 -RequiredAllApprovers
 
    Demonstrates how to set the pull request settings in the `TestRepo` repository as follows:
        Minimum of 2 approvers must approve; All selected approvers must approve
 
    .EXAMPLE
    Set-BBServerPullRequestSetting -Connection $conn -ProjectKey 'TestProject' -RepoName 'TestRepo' -RequiredApprovers 1 -UnapproveOnUpdate $false
 
    Demonstrates how to set the pull request settings in the `TestRepo` repository as follows:
        Minimum of 1 approver must approve; Prior approvals will *not* be removed if the pull request is updated.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [object]
        # An object that defines what Bitbucket Server to connect to and the credentials to use when connecting.
        $Connection,

        [Parameter(Mandatory=$true)]
        [string]
        # The key/ID that identifies the project where the repository resides. This is *not* the project name.
        $ProjectKey,

        [Parameter(Mandatory=$true)]
        [string]
        # The name of a specific repository.
        $RepoName,
        
        [int]
        # The minimum number of users that must approve a pull request before it can be merged.
        $RequiredApprovers,
        
        [boolean]
        # Whether or not all approvers must approve a pull request before it can be merged.
        $RequiredAllApprovers,

        [boolean]
        # Whether or not reviewers approvals will be removed if new commits are pushed or the pull request is retargeted to a different branch.
        $UnapproveOnUpdate
    )
    
    Set-StrictMode -Version 'Latest'
    Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState
    
    $resourcePath = ('projects/{0}/repos/{1}/settings/pull-requests' -f $ProjectKey, $RepoName)
    $pullRequestSettingConfig = @{}
    
    if( $RequiredApprovers )
    {
        $pullRequestSettingConfig += @{ requiredApprovers = $RequiredApprovers }
    }
    
    if( $MyInvocation.BoundParameters.ContainsKey('RequiredAllApprovers') )
    {
        if( $RequiredAllApprovers )
        {
            $pullRequestSettingConfig += @{ requiredAllApprovers = $true }
        }
        else
        {
            $pullRequestSettingConfig += @{ requiredAllApprovers = $false }
        }
    }

    if( $MyInvocation.BoundParameters.ContainsKey('UnapproveOnUpdate') )
    {
        if( $UnapproveOnUpdate )
        {
            $pullRequestSettingConfig += @{ unapproveOnUpdate = $true }
        }
        else
        {
            $pullRequestSettingConfig += @{ unapproveOnUpdate = $false }
        }
    }
    
    $pullRequestSettings = Invoke-BBServerRestMethod -Connection $Connection -Method 'POST' -ApiName 'api' -ResourcePath $resourcePath -InputObject $pullRequestSettingConfig
    
    return $pullRequestSettings
}


# Copyright 2016 - 2018 WebMD Health Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function Use-CallerPreference
{
    <#
    .SYNOPSIS
    Sets the PowerShell preference variables in a module's function based on the callers preferences.
 
    .DESCRIPTION
    Script module functions do not automatically inherit their caller's variables, including preferences set by common parameters. This means if you call a script with switches like `-Verbose` or `-WhatIf`, those that parameter don't get passed into any function that belongs to a module.
 
    When used in a module function, `Use-CallerPreference` will grab the value of these common parameters used by the function's caller:
 
     * ErrorAction
     * Debug
     * Confirm
     * InformationAction
     * Verbose
     * WarningAction
     * WhatIf
     
    This function should be used in a module's function to grab the caller's preference variables so the caller doesn't have to explicitly pass common parameters to the module function.
 
    This function is adapted from the [`Get-CallerPreference` function written by David Wyatt](https://gallery.technet.microsoft.com/scriptcenter/Inherit-Preference-82343b9d).
 
    There is currently a [bug in PowerShell](https://connect.microsoft.com/PowerShell/Feedback/Details/763621) that causes an error when `ErrorAction` is implicitly set to `Ignore`. If you use this function, you'll need to add explicit `-ErrorAction $ErrorActionPreference` to every function/cmdlet call in your function. Please vote up this issue so it can get fixed.
 
    .LINK
    about_Preference_Variables
 
    .LINK
    about_CommonParameters
 
    .LINK
    https://gallery.technet.microsoft.com/scriptcenter/Inherit-Preference-82343b9d
 
    .LINK
    http://powershell.org/wp/2014/01/13/getting-your-script-module-functions-to-inherit-preference-variables-from-the-caller/
 
    .EXAMPLE
    Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
 
    Demonstrates how to set the caller's common parameter preference variables in a module function.
    #>

    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        #[Management.Automation.PSScriptCmdlet]
        # The module function's `$PSCmdlet` object. Requires the function be decorated with the `[CmdletBinding()]` attribute.
        $Cmdlet,

        [Parameter(Mandatory = $true)]
        [Management.Automation.SessionState]
        # The module function's `$ExecutionContext.SessionState` object. Requires the function be decorated with the `[CmdletBinding()]` attribute.
        #
        # Used to set variables in its callers' scope, even if that caller is in a different script module.
        $SessionState
    )

    Set-StrictMode -Version 'Latest'

    # List of preference variables taken from the about_Preference_Variables and their common parameter name (taken from about_CommonParameters).
    $commonPreferences = @{
                              'ErrorActionPreference' = 'ErrorAction';
                              'DebugPreference' = 'Debug';
                              'ConfirmPreference' = 'Confirm';
                              'InformationPreference' = 'InformationAction';
                              'VerbosePreference' = 'Verbose';
                              'WarningPreference' = 'WarningAction';
                              'WhatIfPreference' = 'WhatIf';
                          }

    foreach( $prefName in $commonPreferences.Keys )
    {
        $parameterName = $commonPreferences[$prefName]

        # Don't do anything if the parameter was passed in.
        if( $Cmdlet.MyInvocation.BoundParameters.ContainsKey($parameterName) )
        {
            continue
        }

        $variable = $Cmdlet.SessionState.PSVariable.Get($prefName)
        # Don't do anything if caller didn't use a common parameter.
        if( -not $variable )
        {
            continue
        }

        if( $SessionState -eq $ExecutionContext.SessionState )
        {
            Set-Variable -Scope 1 -Name $variable.Name -Value $variable.Value -Force -Confirm:$false -WhatIf:$false
        }
        else
        {
            $SessionState.PSVariable.Set($variable.Name, $variable.Value)
        }
    }

}