Functions/Public/Start-Stopwatch.ps1

function Start-Stopwatch {
    <#
    .SYNOPSIS
        Starts a named stopwatch for timing code execution.
 
    .DESCRIPTION
        Creates or restarts a stopwatch with the specified name and stores it in a global
        dictionary. Use Stop-Stopwatch to record the elapsed time and Show-StopwatchSummary
        to display all recorded timings.
 
        The stopwatch system uses global scope, making it suitable for timing across
        different scripts and modules.
 
    .PARAMETER Name
        A unique identifier for the stopwatch. Use descriptive names like
        "Data Import", "API Call", or "File Processing".
 
    .PARAMETER ShowStart
        If specified, displays a message when the stopwatch starts.
        Can be controlled globally via $Global:ShowStopwatchStart.
 
    .PARAMETER Quiet
        Suppresses all output, overriding both -ShowStart and global settings.
 
    .PARAMETER PassThru
        Returns the DateTime when the stopwatch was started.
 
    .OUTPUTS
        None by default. DateTime if -PassThru is specified.
 
    .EXAMPLE
        Start-Stopwatch -Name "Data Processing"
        # ... your code ...
        Stop-Stopwatch -Name "Data Processing"
 
    .EXAMPLE
        $Global:ShowStopwatchStart = $true
        Start-Stopwatch -Name "API Call"
        # Output: Starting stopwatch: API Call
 
    .EXAMPLE
        $startTime = Start-Stopwatch -Name "Build" -PassThru
 
    .NOTES
        Author: Sune Alexandersen Narud
        Version: 1.0.0
        Date: February 2026
 
        Part of the Stopwatch timing system:
        - Start-Stopwatch
        - Stop-Stopwatch
        - Get-Stopwatch
        - Reset-Stopwatch
        - Show-StopwatchSummary
 
    .LINK
        Stop-Stopwatch
        Show-StopwatchSummary
        Get-Stopwatch
        Reset-Stopwatch
    #>


    [CmdletBinding()]
    [OutputType([void], [DateTime])]
    param(
        [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)]
        [ValidateNotNullOrEmpty()]
        [string]$Name,

        [Parameter()]
        [switch]$ShowStart,

        [Parameter()]
        [switch]$Quiet,

        [Parameter()]
        [switch]$PassThru
    )

    process {
        # Initialize global dictionaries if needed
        if (-not $Global:OrionStopwatches) {
            $Global:OrionStopwatches = @{}
        }
        if (-not $Global:OrionStopwatchResults) {
            $Global:OrionStopwatchResults = @{}
        }

        # Record the start time
        $startTime = [DateTime]::Now
        $Global:OrionStopwatches[$Name] = $startTime

        # Determine if we should display the start message
        $shouldShow = $false
        if (-not $Quiet) {
            $shouldShow = $ShowStart -or ($Global:ShowStopwatchStart -eq $true)
        }

        if ($shouldShow) {
            Write-Host ""
            Write-Host " ⏱️ Starting stopwatch: " -ForegroundColor DarkGray -NoNewline
            Write-Host "$Name" -ForegroundColor Cyan
        }

        if ($PassThru) {
            return $startTime
        }
    }
}