###############################################################################
#
# load.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]

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

if {[isEagle]} then {
  set load_count [llength [info load]]
} else {
  set load_count 0
}

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

runTest {test load-1.1.1 {load/unload isolated plugin assembly} -setup {
  #
  # HACK: Save the current plugin flags for the interpreter and then
  #       temporarily set them to "Isolated".  The saved flags will
  #       be restored during test cleanup.
  #
  set savedPluginFlags [object invoke -flags +NonPublic \
      Interpreter.GetActive PluginFlags]

  object invoke -flags +NonPublic Interpreter.GetActive \
      PluginFlags Isolated
} -body {
  set file [file nativename [file join $lib_path Plugin1.0 \
      Plugin.dll]]

  list [llength [info loaded]] [load $file Sample.Class3 {}] \
      [llength [info loaded]] [unload -match glob $file \
      "Sample.Class3, *" {}] [llength [info loaded]]
} -cleanup {
  unset -nocomplain file

  object invoke -flags +NonPublic Interpreter.GetActive \
      PluginFlags =$savedPluginFlags

  unset -nocomplain savedPluginFlags
} -constraints {eagle compile.ISOLATED_PLUGINS file_Plugin.dll} -match glob \
-result [list $load_count {{Sample.Class3, Plugin, *} *} \
[expr {$load_count + 1}] {{Sample.Class3, Plugin, *} *} $load_count]}

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

runTest {test load-1.1.2 {load/unload non-isolated plugin assembly} -body {
  set file [file nativename [file join $lib_path Plugin1.0 \
      Plugin.dll]]

  list [llength [info loaded]] [load $file Sample.Class3 {}] \
      [llength [info loaded]] [unload -match glob $file \
      "Sample.Class3, *" {}] [llength [info loaded]]
} -cleanup {
  unset -nocomplain file
} -constraints \
[fixConstraints {eagle !compile.ISOLATED_PLUGINS file_Plugin.dll}] \
-match glob -result [list $load_count {{Sample.Class3, Plugin, *} *} \
[expr {$load_count + 1}] {{Sample.Class3, Plugin, *} *} $load_count]}

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

if {[isEagle]} then {
  set interp [interp create]
  set load_count [interp eval $interp {llength [info load]}]
} else {
  set load_count 0
}

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

runTest {test load-1.2.1 {load/unload isolated plugin assembly} -setup {
  #
  # HACK: Save the current plugin flags for the interpreter and then
  #       temporarily set them to "Isolated".  The saved flags will
  #       be restored during test cleanup.
  #
  interp eval $interp {
    set savedPluginFlags [object invoke -flags +NonPublic \
        Interpreter.GetActive PluginFlags]

    object invoke -flags +NonPublic Interpreter.GetActive \
        PluginFlags Isolated
  }
} -body {
  set file [file nativename [file join $lib_path Plugin1.0 \
      Plugin.dll]]

  list [interp eval $interp {llength [info loaded]}] \
      [load $file Sample.Class3 $interp] \
      [interp eval $interp {llength [info loaded]}] \
      [unload -match glob $file "Sample.Class3, *" $interp] \
      [interp eval $interp {llength [info loaded]}]
} -cleanup {
  unset -nocomplain file

  interp eval $interp {
    object invoke -flags +NonPublic Interpreter.GetActive \
        PluginFlags =$savedPluginFlags

    unset -nocomplain savedPluginFlags
  }
} -constraints {eagle compile.ISOLATED_PLUGINS file_Plugin.dll} -match glob \
-result [list $load_count {{Sample.Class3, Plugin, *} *} \
[expr {$load_count + 1}] {{Sample.Class3, Plugin, *} *} $load_count]}

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

runTest {test load-1.2.2 {load/unload non-isolated plugin assembly} -body {
  set file [file nativename [file join $lib_path Plugin1.0 \
      Plugin.dll]]

  list [interp eval $interp {llength [info loaded]}] \
      [load $file Sample.Class3 $interp] \
      [interp eval $interp {llength [info loaded]}] \
      [unload -match glob $file "Sample.Class3, *" $interp] \
      [interp eval $interp {llength [info loaded]}]
} -cleanup {
  unset -nocomplain file
} -constraints \
[fixConstraints {eagle !compile.ISOLATED_PLUGINS file_Plugin.dll}] \
-match glob -result [list $load_count {{Sample.Class3, Plugin, *} *} \
[expr {$load_count + 1}] {{Sample.Class3, Plugin, *} *} $load_count]}

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

runTest {test load-1.3 {plugin Execute method} -setup {
  set type Eagle._Plugins.Test; package require $type

  set plugin [object invoke -alias -flags +NonPublic \
      Interpreter.GetActive GetPlugin [lindex [lindex \
      [info loaded [appendArgs *\{ $type ,*]] 0] end]]

  set savedEnableExecute [$plugin Object.EnableExecute]
  $plugin Object.EnableExecute true
} -body {
  list [set response null] [set error null] [$plugin Execute "" null \
      "one two" response error] [testArrayGet $response true] [expr {[string \
      length $error] > 0 ? [object invoke $error ToString] : ""}] [set \
      response null] [set error null] [$plugin Execute "" [set clientData \
      [object create ClientData "three four"]] "five six" response error] \
      [catch {testArrayGet response true} result] $result [expr {[string \
      length $error] > 0 ? [object invoke $error ToString] : ""}]
} -cleanup {
  catch {$plugin Object.EnableExecute $savedEnableExecute}

  unset -nocomplain result clientData error response code savedEnableExecute \
      plugin type
} -constraints {eagle configuration.Debug} -match regexp -result {^null null\
Error \{\} \{invalid clientData\} null null Ok 0 \{0 Interpreter#\d+ 1 \{three\
four\} 2 \{five six\}\} \{\}$}}

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

runTest {test load-1.4 {plugin GetStream method} -setup {
  set type Eagle._Plugins.Test; package require $type

  set plugin [object invoke -alias -flags +NonPublic \
      Interpreter.GetActive GetPlugin [lindex [lindex \
      [info loaded [appendArgs *\{ $type ,*]] 0] end]]

  set savedEnableGetStream [$plugin Object.EnableGetStream]
  $plugin Object.EnableGetStream true
} -body {
  list [set error null] [set stream1 [$plugin GetStream "" Eagle.xsd \
      error]] [expr {[string length $error] > 0 ? [object invoke $error \
      ToString] : ""}] [set error null] [set stream2 [$plugin GetStream "" \
      NotThere error]] [expr {[string length $error] > 0 ? [object invoke \
      $error ToString] : ""}]
} -cleanup {
  catch {$plugin Object.EnableGetStream $savedEnableGetStream}

  unset -nocomplain error stream2 stream1 savedEnableGetStream plugin type
} -constraints {eagle configuration.Debug} -match regexp -result {^null\
System#IO#UnmanagedMemoryStream#\d+ \{\} null \{\} \{stream not found\}$}}

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

runTest {test load-1.5 {plugin GetString method} -setup {
  set type Eagle._Plugins.Test; package require $type

  set plugin [object invoke -alias -flags +NonPublic \
      Interpreter.GetActive GetPlugin [lindex [lindex \
      [info loaded [appendArgs *\{ $type ,*]] 0] end]]

  set savedEnableGetString [$plugin Object.EnableGetString]
  $plugin Object.EnableGetString true
} -body {
  list [set error null] [$plugin GetString "" null null error] [expr \
      {[string length $error] > 0 ? [object invoke $error ToString] : ""}] \
      [set error null] [$plugin GetString "" testing null error] [expr \
      {[string length $error] > 0 ? [object invoke $error ToString] : ""}]
} -cleanup {
  catch {$plugin Object.EnableGetString $savedEnableGetString}

  unset -nocomplain error savedEnableGetString plugin type
} -constraints {eagle configuration.Debug} -result {null {} {invalid string\
name} null {interpreter: "1", name: "testing", cultureInfo: <null>} {}}}

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

runTest {test load-1.6 {load plugin via bytes (non-isolated)} -setup [subst {
  unset -nocomplain code result token plugin fileName haveCasPolicy

  set haveCasPolicy [haveConstraint compile.CAS_POLICY]
  set fileName {[file nativename [file join $lib_path Plugin1.0 Plugin.dll]]}
}] -body {
  set plugin null; set token 0; set result null

  if {$haveCasPolicy} then {
    set code [object invoke -alias \
        Eagle._Tests.Default TestLoadPluginViaBytes "" $fileName null \
        Sample.Class3 null None plugin token result]
  } else {
    set code [object invoke -alias \
        Eagle._Tests.Default TestLoadPluginViaBytes "" $fileName \
        Sample.Class3 null None plugin token result]
  }

  list $code [expr {[string length $result] > 0 ? [$result ToString] : ""}] \
      $plugin $token
} -cleanup {
  unset -nocomplain code result token plugin fileName haveCasPolicy
} -constraints {eagle monoCrash28 compile.TEST file_Plugin.dll\
Eagle._Tests.Default.TestLoadPluginViaBytes strongName.official} \
-isolationLevel Maximum -match regexp -result {^Ok \{\{Sample\.Class3, Plugin,\
Version=1\.0\.\d+.\d+, Culture=neutral,\
PublicKeyToken=(?:null|29c6297630be05eb|1e22ec67879739a2|358030063a832bc3)\}\
1\.0\.\d+.\d+\} Sample#Class3#\d+ \d+$}}

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

runTest {test load-1.7 {load plugin via bytes (isolated)} -setup [subst {
  unset -nocomplain code result token plugin fileName haveCasPolicy \
      savedPluginFlags

  set haveCasPolicy [haveConstraint compile.CAS_POLICY]
  set fileName {[file nativename [file join $lib_path Plugin1.0 Plugin.dll]]}

  #
  # HACK: Save the current plugin flags for the interpreter and then
  #       temporarily set them to "Isolated".  The saved flags will
  #       be restored during test cleanup.
  #
  set savedPluginFlags \[object invoke -flags +NonPublic \
      Interpreter.GetActive PluginFlags\]

  object invoke -flags +NonPublic Interpreter.GetActive \
      PluginFlags Isolated
}] -body {
  set plugin null; set token 0; set result null

  if {$haveCasPolicy} then {
    set code [object invoke -alias \
        Eagle._Tests.Default TestLoadPluginViaBytes "" $fileName null \
        Sample.Class3 null None plugin token result]
  } else {
    set code [object invoke -alias \
        Eagle._Tests.Default TestLoadPluginViaBytes "" $fileName \
        Sample.Class3 null None plugin token result]
  }

  list $code [expr {[string length $result] > 0 ? [$result ToString] : ""}] \
      $plugin $token
} -cleanup {
  object invoke -flags +NonPublic Interpreter.GetActive \
      PluginFlags =$savedPluginFlags

  unset -nocomplain code result token plugin fileName haveCasPolicy \
      savedPluginFlags
} -constraints {eagle compile.ISOLATED_PLUGINS compile.TEST file_Plugin.dll\
Eagle._Tests.Default.TestLoadPluginViaBytes strongName.official} \
-isolationLevel Maximum -match regexp -result {^Ok \{\{Sample\.Class3, Plugin,\
Version=1\.0\.\d+.\d+, Culture=neutral,\
PublicKeyToken=(?:null|29c6297630be05eb|1e22ec67879739a2|358030063a832bc3)\}\
1\.0\.\d+.\d+\} Sample#Class3#\d+ \d+$}}

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

unset -nocomplain load_count

if {[isEagle]} then {
  catch {interp delete $interp}
  unset -nocomplain interp
}

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

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