###############################################################################
#
# array2.eagle --
#
# Extensible Adaptable Generalized Logic Engine (Eagle)
#
# Copyright (c) 2007-2012 by Joe Mistachkin.  All rights reserved.
#
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: $
#
###############################################################################

source [file join [file normalize [file dirname [info script]]] prologue.eagle]

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

runTest {test array-2.1 {set element} -setup {
  unset -nocomplain foo
} -body {
  set foo(bar) 2
} -cleanup {
  unset -nocomplain foo
} -result {2}}

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

runTest {test array-2.2 {set escaped element} -setup {
  unset -nocomplain foo
} -body {
  set {foo(bar)} 2; return ${foo(bar)}
} -cleanup {
  unset -nocomplain foo
} -result {2}}

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

runTest {test array-3.1 {[array set] with new & existing arrays} -setup {
  unset -nocomplain a b c m
} -body {
  set c 0; # scalar
  list [array set a {1 2 3 4}] [testArrayGet a true] \
      [array set a {1 0 5 6}] [testArrayGet a true] \
      [array set b {7 8 9 A}] [testArrayGet b true] \
      [unset b] [set b B] [unset b] [array set b {C D E F}] \
      [catch {array set c {G H I J}} m] $m [catch {testArrayGet c true} m] $m
} -cleanup {
  unset -nocomplain a b c m
} -match regexp -result {^\{\} \{1 2 3 4\} \{\} \{1 0 3 4 5 6\} \{\} \{7 8 9\
A\} \{\} B \{\} \{\} 1 \{(?:"c" isn't an array|can't set "c\(G\)": variable\
isn't array)\} 0 \{\}$}}

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

runTest {test array-3.2 {[array set] existing array with references} -setup {
  unset -nocomplain a b m
} -body {
  set a(x) [object create -alias Random]
  set b [object create -alias Random]
  list [catch {object refcount $a(x)} m] $m [catch {object refcount $b} m] \
      $m [catch {$a(x) Next} m] [catch {$b Next} m] \
      [catch {testArrayGet a true} m] $m [array set a {1 2}] [array set a \
      [list 3 $b]] [catch {object refcount $a(x)} m] $m [catch {object \
      refcount $b} m] $m [catch {$a(x) Next} m] [catch {$b Next} m] \
      [catch {testArrayGet a} m] $m [array set a {3 4}] \
      [catch {object refcount $a(x)} m] $m [catch {object refcount $b} m] $m \
      [catch {$a(x) Next} m] [catch {$b Next} m]
} -cleanup {
  unset -nocomplain a b m
} -constraints {eagle refCount} -match regexp -result {^0 1 0 1 0 0 0 \{x\
System#Random#\d+\} \{\} \{\} 0 1 0 2 0 0 0 \{1 2 3 System#Random#\d+ x\
System#Random#\d+\} \{\} 0 1 0 1 0 0$}}

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

#
# MONO: The [lrepeat] used to calculate the result of test "array-4.1" does not
#       work properly on Mono when the native utility library is in use, due to
#       a StackOverflowException being thrown.
#
if {[isEagle] && [haveConstraint bigLists]} then {
  catch {purgeAndCleanup $test_channel before}

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

  unset -nocomplain test_log_if
  set test_log_if [expr {[info exists test_log] ? $test_log : ""}]

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

  runTest {test array-4.1 {marshalling large byte arrays byRef} -setup [subst \
      -nocommands -nobackslashes {
    unset -nocomplain output input code error original test

    #
    # NOTE: Set the channel to use for test output, if necessary.
    #
    if {![info exists test_channel]} then {
      set test_channel {$test_channel}
    }

    #
    # NOTE: Check for and load the Eagle test package, if necessary.
    #
    if {[catch {package present Eagle.Test}]} then {
      package require Eagle.Test
    }

    #
    # NOTE: Set the log file name to use for test output, if necessary.
    #
    if {![info exists test_log]} then {
      set test_log {$test_log_if}
    }

    object import System.Text
  }] -body {
    set test [object create -alias Eagle._Tests.Default]
    set original [string repeat "this is a test." 100000]; # 1500000 bytes

    catch {unset input}
    set input [object invoke -create Encoding.UTF8 GetBytes $original]
    catch {unset output}; array set output {}
    set error null

    tputs $test_channel [appendArgs \
        "---- done marshalling " [string length $original] \
        " byte array via handle/elements in " \
        [time {set code [$test -argumentflags +Direct \
        TestTwoByteArrays "" false $input output error]}] \n]

    if {$code ne "Ok"} then {
      error [object invoke $error ToString]
    }

    catch {unset input}
    array set input [array get output]; # EXEMPT: Ordering does not matter.
    catch {unset output}; array set output {}
    set error null

    tputs $test_channel [appendArgs \
        "---- done marshalling " [array size input] \
        " byte array via elements/elements in " \
        [time {set code [$test -argumentflags +Direct \
        TestTwoByteArrays "" false input output error]}] \n]

    if {$code ne "Ok"} then {
      error [object invoke $error ToString]
    }

    $test TestReturnByteArray output
  } -cleanup {
    object unimport -importpattern System.Text

    unset -nocomplain output input code error original test
  } -constraints {eagle monoCrash33 Eagle._Tests.Default.TestTwoByteArrays\
Eagle._Tests.Default.TestReturnByteArray} -isolationLevel Interpreter -result \
[lrepeat 100000 116 104 105 115 32 105 115 32 97 32 116 101 115 116 46]}

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

  runTest {test array-4.2 {marshalling byte arrays as object} -setup [subst \
      -nocommands -nobackslashes {
    unset -nocomplain output input code error original test

    #
    # NOTE: Set the channel to use for test output, if necessary.
    #
    if {![info exists test_channel]} then {
      set test_channel {$test_channel}
    }

    #
    # NOTE: Check for and load the Eagle test package, if necessary.
    #
    if {[catch {package present Eagle.Test}]} then {
      package require Eagle.Test
    }

    #
    # NOTE: Set the log file name to use for test output, if necessary.
    #
    if {![info exists test_log]} then {
      set test_log {$test_log_if}
    }

    object import System.Text
  }] -body {
    set test [object create -alias Eagle._Tests.Default]
    set original [string repeat "this is a test." 100000]; # 1500000 bytes

    catch {unset input}
    set input [object invoke -create Encoding.UTF8 GetBytes $original]
    catch {unset output}; set output null
    set error null

    tputs $test_channel [appendArgs \
        "---- done marshalling " [object invoke $input Length] \
        " byte array value via handle/variable in " \
        [time {set code [$test -argumentflags Create -arrayasvalue \
        TestTwoByteArrays "" false $input output error]}] \n]

    if {$code ne "Ok"} then {
      error [object invoke $error ToString]
    }

    catch {unset input}
    set input $output
    catch {unset output}; set output null
    set error null

    tputs $test_channel [appendArgs \
        "---- done marshalling " [object invoke $input Length] \
        " byte array value via handle/handle in " \
        [time {set code [$test -argumentflags Create -arrayasvalue \
        TestTwoByteArrays "" false input output error]}] \n]

    if {$code ne "Ok"} then {
      error [object invoke $error ToString]
    }

    $test TestReturnByteArray output
  } -cleanup {
    object unimport -importpattern System.Text

    unset -nocomplain output input code error original test
  } -constraints {eagle monoCrash33 Eagle._Tests.Default.TestTwoByteArrays\
Eagle._Tests.Default.TestReturnByteArray} -isolationLevel Interpreter -result \
[lrepeat 100000 116 104 105 115 32 105 115 32 97 32 116 101 115 116 46]}

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

  runTest {test array-4.3 {marshalling byte arrays as links} -setup [subst \
      -nocommands -nobackslashes {
    unset -nocomplain output input code error original test

    #
    # NOTE: Set the channel to use for test output, if necessary.
    #
    if {![info exists test_channel]} then {
      set test_channel {$test_channel}
    }

    #
    # NOTE: Check for and load the Eagle test package, if necessary.
    #
    if {[catch {package present Eagle.Test}]} then {
      package require Eagle.Test
    }

    #
    # NOTE: Set the log file name to use for test output, if necessary.
    #
    if {![info exists test_log]} then {
      set test_log {$test_log_if}
    }

    object import System.Text
  }] -body {
    set test [object create -alias Eagle._Tests.Default]
    set original [string repeat "this is a test." 100000]; # 1500000 bytes

    catch {unset input}
    set input [object invoke -create Encoding.UTF8 GetBytes $original]
    catch {unset output}; set output null
    set error null

    tputs $test_channel [appendArgs \
        "---- done marshalling " [object invoke $input Length] \
        " byte array value via handle/link in " \
        [time {set code [$test -argumentflags Create -arrayaslink \
        TestTwoByteArrays "" false $input output error]}] \n]

    if {$code ne "Ok"} then {
      error [object invoke $error ToString]
    }

    catch {unset input}
    array copy -deep output input
    catch {unset output}; set output null

    tputs $test_channel [appendArgs \
        "---- done marshalling " [array size input] \
        " byte array value via link/link in " \
        [time {set code [$test -argumentflags Create -arrayaslink \
        TestTwoByteArrays "" false input output error]}] \n]

    if {$code ne "Ok"} then {
      error [object invoke $error ToString]
    }

    $test TestReturnByteArray output
  } -cleanup {
    object unimport -importpattern System.Text

    unset -nocomplain output input code error original test
  } -constraints {eagle monoCrash33 Eagle._Tests.Default.TestTwoByteArrays\
Eagle._Tests.Default.TestReturnByteArray} -isolationLevel Interpreter -result \
[lrepeat 100000 116 104 105 115 32 105 115 32 97 32 116 101 115 116 46]}

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

  catch {purgeAndCleanup $test_channel after}

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

  unset -nocomplain test_log_if
}

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

source [file join [file normalize [file dirname [info script]]] epilogue.eagle]
