# Structure of this test:
# =======================

# First we test that the different watchers correctly detect events such as changing a file, creating a new file,
# changing that new file, and deleting a file.

# Then we test the specifics of the reloader - for example, ensuring that it only reloads when the classpath changes,
# and testing failure conditions.

# Additionally, when making assertions about reloads, we need to wait at least a second after changing the file before
# we make a request.  The reason for this is that the classpath change detection is based on file modification times,
# which only have 1 second precision

# Watcher tests
# -------------

# sbt watcher
# - - - - - -

# Start dev mode
> run

# Existing file change detection
> verifyResourceContains /assets/css/some.css 200 original
$ copy-file changes/some.css.1 public/css/some.css
> verifyResourceContains /assets/css/some.css 200 first
$ delete public/css/some.css
> verifyResourceContains /assets/css/some.css 404

# New file change detection
> verifyResourceContains /assets/new/new.css 404
$ copy-file changes/new.css public/new/new.css
> verifyResourceContains /assets/new/new.css 200 original
# Need to wait a little while, because incremental compilation timestamps.
$ sleep 1000
$ copy-file changes/new.css.1 public/new/new.css
> verifyResourceContains /assets/new/new.css 200 first
$ delete public/new/new.css
> verifyResourceContains /assets/new/new.css 404

# Two files with the same name change detection
> verifyResourceContains /assets/a/some.txt 200 original
> verifyResourceContains /assets/b/some.txt 200 original
# These sleeps are necessary to ensure a full second has ticked by since the last modified timestamp was captured
$ sleep 1000
$ copy-file changes/some.txt.1 public/a/some.txt
> verifyResourceContains /assets/a/some.txt 200 changed
$ sleep 1000
$ copy-file changes/some.txt.1 public/b/some.txt
> verifyResourceContains /assets/b/some.txt 200 changed

> playStop
$ copy-file changes/some.css.0 public/css/some.css
$ copy-file changes/some.txt.0 public/a/some.txt
$ copy-file changes/some.txt.0 public/b/some.txt
$ delete public/new
> clean

# JDK7 watcher
# - - - - - -

> set PlayKeys.fileWatchService := DevModeBuild.jdk7WatchService.value

# Start dev mode
> run

# Existing file change detection
> verifyResourceContains /assets/css/some.css 200 original
$ copy-file changes/some.css.1 public/css/some.css
> verifyResourceContains /assets/css/some.css 200 first
$ delete public/css/some.css
> verifyResourceContains /assets/css/some.css 404

# New file change detection
> verifyResourceContains /assets/new/new.css 404
$ copy-file changes/new.css public/new/new.css
> verifyResourceContains /assets/new/new.css 200 original
# Need to wait a little while, because incremental compilation timestamps.
$ sleep 1000
$ copy-file changes/new.css.1 public/new/new.css
> verifyResourceContains /assets/new/new.css 200 first
$ delete public/new/new.css
> verifyResourceContains /assets/new/new.css 404

# Two files with the same name change detection
> verifyResourceContains /assets/a/some.txt 200 original
> verifyResourceContains /assets/b/some.txt 200 original
$ copy-file changes/some.txt.1 public/a/some.txt
> verifyResourceContains /assets/a/some.txt 200 changed
$ copy-file changes/some.txt.1 public/b/some.txt
> verifyResourceContains /assets/b/some.txt 200 changed

> playStop
$ copy-file changes/some.css.0 public/css/some.css
$ copy-file changes/some.txt.0 public/a/some.txt
$ copy-file changes/some.txt.0 public/b/some.txt
$ delete public/new
> clean

# JNotify watch service
# - - - - - - - - - - -

> set PlayKeys.fileWatchService := DevModeBuild.jnotifyWatchService.value

# Start dev mode
> run

# Existing file change detection
> verifyResourceContains /assets/css/some.css 200 original
$ copy-file changes/some.css.1 public/css/some.css
> verifyResourceContains /assets/css/some.css 200 first
$ delete public/css/some.css
> verifyResourceContains /assets/css/some.css 404

# New file change detection
> verifyResourceContains /assets/new/new.css 404
$ copy-file changes/new.css public/new/new.css
> verifyResourceContains /assets/new/new.css 200 original
# Need to wait a little while, because incremental compilation timestamps.
$ sleep 1000
$ copy-file changes/new.css.1 public/new/new.css
> verifyResourceContains /assets/new/new.css 200 first
$ delete public/new/new.css
> verifyResourceContains /assets/new/new.css 404

# Two files with the same name change detection
> verifyResourceContains /assets/a/some.txt 200 original
> verifyResourceContains /assets/b/some.txt 200 original
$ copy-file changes/some.txt.1 public/a/some.txt
> verifyResourceContains /assets/a/some.txt 200 changed
$ copy-file changes/some.txt.1 public/b/some.txt
> verifyResourceContains /assets/b/some.txt 200 changed

> playStop
$ copy-file changes/some.css.0 public/css/some.css
$ copy-file changes/some.txt.0 public/a/some.txt
$ copy-file changes/some.txt.0 public/b/some.txt
$ delete public/new
> clean

# Reloader tests
# --------------

> resetReloads
> run

# Check various action types
> verifyResourceContains / 200 original
> verifyResourceContains /assets/css/some.css 200 original
> verifyResourceContains /assets/main.css 200 original
> verifyReloads 1

# Wait a while and ensure we still haven't reloaded
$ sleep 1000
> verifyResourceContains / 200
> verifyReloads 1

# Change a scala file
$ sleep 1000
$ copy-file changes/Application.scala.1 app/controllers/Application.scala
> verifyResourceContains / 200 first
> verifyReloads 2

# Change a static asset
$ sleep 1000
$ copy-file changes/some.css.1 public/css/some.css
> verifyResourceContains /assets/css/some.css 200 first
# No reloads should have happened
> verifyReloads 2

# Change a compiled asset
$ sleep 1000
$ copy-file changes/main.less.1 app/assets/main.less
> verifyResourceContains /assets/main.css 200 first
# No reloads should have happened
> verifyReloads 2

# Introduce a compile error
$ sleep 1000
$ copy-file changes/Application.scala.2 app/controllers/Application.scala
> verifyResourceContains / 500
> verifyReloads 2

# Fix the compile error
$ sleep 1000
$ copy-file changes/Application.scala.3 app/controllers/Application.scala
> verifyResourceContains / 200 second
> verifyReloads 3

# Change a resource (also introduces a startup failure)
$ sleep 1000
# Making a copy so that we can revert to it later
$ copy-file conf/application.conf conf/application.original
$ copy-file changes/application.conf.1 conf/application.conf
> verifyResourceContains / 500
> verifyReloads 4

# Revert to the original application.conf
$ sleep 1000
$ copy-file conf/application.original conf/application.conf
> verifyResourceContains / 200

> playStop

# devSettings tests
# -----------------

# First a test without the dev-setting to ensure everything works
> run
> makeRequestWithHeader / 200 this-is-a-header-name-longer-than-32-chars
> playStop

# A test overriding a akka setting that should be picked by dev mode
> set PlayKeys.devSettings ++= Seq("akka.http.parsing.max-header-name-length" -> "32 bytes")
> run
> makeRequestWithHeader / 431 this-is-a-header-name-longer-than-32-chars
> playStop

# Should prioritize play.akka.dev-mode
> set PlayKeys.devSettings ++= Seq("play.akka.dev-mode.akka.http.parsing.max-header-name-length" -> "32 bytes")

# This should NOT be picked
> set PlayKeys.devSettings ++= Seq("akka.http.parsing.max-header-name-length" -> "1 megabyte")
> run
> makeRequestWithHeader / 431 this-is-a-header-name-longer-than-32-chars
> playStop