#
# Copyright (c) 2010, Ashok P. Nadkarni
# All rights reserved.
#
# See the file LICENSE for license

# This file contains tests for power related commands.

package require tcltest
eval tcltest::configure $argv

source [file join [file dirname [info script]] testutil.tcl]
load_twapi_package twapi_power
package require twapi_base

if {[tcltest::testConstraint userInteraction] &&
    [twapi::kl_get [twapi::get_power_status] -batterystate] ne "unknown" &&
    ! [tcltest::testConstraint powertests]
} {
    tcltest::testConstraint powertests [yesno "Do you want to run the power tests on this system?"]
}

#
# Set up system-specific constants that are used to match test results
namespace eval twapi::power::test {
    namespace import ::tcltest::test

    ################################################################

    test get_power_status-1.0 {
        Get power status
    } -body {
        array set ps [twapi::get_power_status]
        expr {
              [oneof {on off unknown} $ps(-acstatus)] &&
              [oneof {critical low high unknown notpresent} $ps(-batterystate)] &&
              [oneof {true false unknown} $ps(-batterycharging)] &&
              ($ps(-batterylifepercent) eq "unknown" || [string is integer -strict $ps(-batterylifepercent)]) &&
              ($ps(-batterylifetime) eq "unknown" || [string is integer -strict $ps(-batterylifetime)]) &&
              ($ps(-batteryfulllifetime) eq "unknown" || [string is integer -strict $ps(-batteryfulllifetime)])
          }
    } -result 1

    
    ################################################################

    test start_power_monitor-1.0 {
        Monitor power changes - apmpowerstatuschange
    } -constraints {
        userInteraction powertests
    } -body {
        set ::power_notification ""
        set hpower [twapi::start_power_monitor "lappend ::power_notification"]
        set after_id [after 15000 "set ::power_notification timeout"]
        pause "Please turn off A/C power and hit return."
        vwait ::power_notification
        after cancel $after_id
        twapi::stop_power_monitor $hpower
        pause "Turn on A/C power and hit return."
        lindex $::power_notification 0
    } -result apmpowerstatuschange

    proc suspend_handler {event args} {
        lappend ::power_notification_state $event
        if {[llength $::power_notification_state] == 4} {
            set ::power_notification $::power_notification_state
        }
        return 1
    }

    proc suspend_abort_handler {event args} {
        set ::power_notification $event
        if {$event eq "apmquerysuspend"} {
            return 0
        } else {
            return 1
        }
    }

    test start_power_monitor-2.0 {
        Monitor power changes - suspend / resume sequence
    } -constraints {
        userInteraction powertests
    } -body {
        if {![yesno "This test requires the system to be placed in standby. Do you want to run the test?"]} {
            error "Test skipped as per user instruction."
        }
        set ::power_notification ""
        set ::power_notification_state {}
        set hpower [twapi::start_power_monitor [namespace current]::suspend_handler]
        set after_id [after 30000 "set ::power_notification timeout"]
        puts "Please suspend and resume the system."
        vwait ::power_notification
        after cancel $after_id
        twapi::stop_power_monitor $hpower
        set ::power_notification_state
    } -result {apmquerysuspend apmsuspend apmresumeautomatic apmresumesuspend}


    ################################################################

    test stop_power_monitor-1.0 {
        Stop monitor power changes
    } -constraints {
        userInteraction powertests
    } -setup {
        set ::power_notification ""
        set hpower [twapi::start_power_monitor "lappend ::power_notification"]
        set after_id [after 15000 "set ::power_notification timeout"]
        pause "Please turn OFF A/C power. (Do NOT turn it back ON.)"
        vwait ::power_notification
        after cancel $after_id
        twapi::stop_power_monitor $hpower
        if {$::power_notification eq "timeout"} {
            error "Could not set up power notifications."
        }
    } -body {
        set after_id [after 10000 "set ::power_notification timeout"]
        pause "Please turn ON A/C power."
        vwait ::power_notification
        after cancel $after_id
        set ::power_notification
    } -result timeout

    #
    # Clean up
    ::tcltest::cleanupTests
}

namespace delete ::twapi::power::test
