# progress.test --
#
# Tests transfer completion and progress callbacks.
#
# Copyright (c) 2024-2026 Massimo Manghi
#
# SPDX-License-Identifier: TCL
#
# See the file "license.terms" at the top level of this distribution
# for information on usage and redistribution of this file, and for the
# complete disclaimer of warranties and limitation of liability.
#
# Portions of this file were drafted or revised with AI assistance
# under the direction and review of Massimo Manghi

package require tcltest
namespace import ::tcltest::*

source [file join [file dirname [file normalize [info script]]] support.tcl]

::tclcurl::test::load_package

proc ::tclcurl::test::command_probe {} {
    incr ::tclcurl::test::command_calls
    return 0
}

proc ::tclcurl::test::progress_probe {dltotal dlnow ultotal ulnow} {
    incr ::tclcurl::test::progress_calls
    set ::tclcurl::test::progress_last [list $dltotal $dlnow $ultotal $ulnow]
    if {$dltotal > $::tclcurl::test::progress_max_dltotal} {
        set ::tclcurl::test::progress_max_dltotal $dltotal
    }
    if {$dlnow > $::tclcurl::test::progress_max_dlnow} {
        set ::tclcurl::test::progress_max_dlnow $dlnow
    }
    return 0
}

proc ::tclcurl::test::progress_pause_probe {dltotal dlnow ultotal ulnow} {
    incr ::tclcurl::test::progress_calls
    set ::tclcurl::test::progress_last [list $dltotal $dlnow $ultotal $ulnow]

    if {!$::tclcurl::test::pause_done && ($dlnow > 0)} {
        set ::tclcurl::test::pause_done 1
        incr ::tclcurl::test::pause_count
        set ::tclcurl::test::pause_start_dlnow $dlnow
        set pause_started_ms [clock milliseconds]
        $::tclcurl::test::progress_handle pause
        after $::tclcurl::test::pause_duration_ms
        $::tclcurl::test::progress_handle resume
        incr ::tclcurl::test::pause_total_ms [expr {[clock milliseconds] - $pause_started_ms}]
    } elseif {$::tclcurl::test::pause_done && !$::tclcurl::test::resume_seen && ($dlnow > 0)} {
        set ::tclcurl::test::resume_seen 1
        set ::tclcurl::test::resume_seen_dlnow $dlnow
    }

    return 0
}

test progress-1.1 {-command runs after a successful transfer} -constraints http_server -body {
    set ::tclcurl::test::command_calls 0
    set body {}
    ::tclcurl::test::with_easy_handle handle {
        $handle configure -url [::tclcurl::test::server::base_url] \
                          -command ::tclcurl::test::command_probe \
                          -bodyvar body \
                          -noprogress 1
        set rc [$handle perform]
        list $rc \
             [$handle getinfo responsecode]     \
             $::tclcurl::test::command_calls    \
             [expr {[string length $body] > 0}]
    }
} -result {0 200 1 1}

test progress-1.2 {-progressproc reports download progress during transfer} -constraints http_server -body {
    set ::tclcurl::test::progress_calls         0
    set ::tclcurl::test::progress_last          {}
    set ::tclcurl::test::progress_max_dltotal   0
    set ::tclcurl::test::progress_max_dlnow     0
    set body {}
    ::tclcurl::test::with_easy_handle handle {
        $handle configure -url          [::tclcurl::test::server::base_url slow-body-2] \
                          -progressproc ::tclcurl::test::progress_probe \
                          -bodyvar      body \
                          -noprogress   0
        set rc [$handle perform]
        list $rc \
             [$handle getinfo responsecode]         \
             [expr {$::tclcurl::test::progress_calls > 0}] \
             [expr {[llength $::tclcurl::test::progress_last] == 4}] \
             [string length $body]
    }
} -result [list 0 200 1 1 192]

test progress-1.3 {-buffersize accepts a valid integer value} -constraints http_server -body {
    set body {}
    ::tclcurl::test::with_easy_handle handle {
        $handle configure -url [::tclcurl::test::server::base_url range-data] \
                          -buffersize 4096 \
                          -bodyvar body \
                          -noprogress 1
        set rc [$handle perform]
        list $rc \
             [$handle getinfo responsecode] \
             [string length $body]
    }
} -result [list 0 200 131072]

test progress-1.4 {-buffersize rejects malformed values} -constraints http_server -body {
    ::tclcurl::test::with_easy_handle handle {
        list [catch {
                  $handle configure -url [::tclcurl::test::server::base_url range-data] \
                                    -buffersize bogus \
                                    -noprogress 1
              } result] $result
    }
} -result {1 {setting option -buffersize: bogus}}

test progress-1.5 {-progressproc can pause and resume a transfer} -constraints http_server -body {
    set expectedSize 192
    set ::tclcurl::test::progress_calls     0
    set ::tclcurl::test::progress_last      {}
    set ::tclcurl::test::progress_handle    {}
    set ::tclcurl::test::pause_done         0
    set ::tclcurl::test::pause_count        0
    set ::tclcurl::test::pause_duration_ms  300
    set ::tclcurl::test::pause_total_ms     0
    set ::tclcurl::test::pause_start_dlnow  0
    set ::tclcurl::test::resume_seen        0
    set ::tclcurl::test::resume_seen_dlnow  0
    set body {}
    set started_ms [clock milliseconds]
    ::tclcurl::test::with_easy_handle handle {
        set ::tclcurl::test::progress_handle $handle
        $handle configure -url [::tclcurl::test::server::base_url slow-body-2] \
                          -progressproc ::tclcurl::test::progress_pause_probe \
                          -buffersize 1024 \
                          -bodyvar body \
                          -noprogress 0
        set rc [$handle perform]
        set elapsed_ms [expr {[clock milliseconds] - $started_ms}]
        list $rc    [$handle getinfo responsecode] \
                    [expr {$::tclcurl::test::pause_count == 1}] \
                    [expr {$::tclcurl::test::pause_total_ms >= $::tclcurl::test::pause_duration_ms}] \
                    [expr {$elapsed_ms >= $::tclcurl::test::pause_duration_ms}] \
                    [expr {$::tclcurl::test::pause_start_dlnow > 0}] \
                    [string length $body]
    }
} -result [list 0 200 1 1 1 1 192]

cleanupTests
