package quickstart.action

import scala.concurrent._

import io.netty.channel.{ChannelFuture, ChannelFutureListener}

import xitrum.{Action, ActorAction, FutureAction, Config}
import xitrum.annotation.GET
import xitrum.etag.NotModified

@GET("")
class SiteIndex extends DefaultLayout {
  def execute() {
    respondView()
  }
}

trait MyFilter {
  this: Action =>

  beforeFilter {
    logging("Before filter")
  }

  afterFilter {
    logging("After filter")
  }

  aroundFilter { action =>
    logging("Before around filter")
    action()
    logging("After around filter")
  }

  def logging(msg: String) {
    log.info(System.currentTimeMillis() + " " + msg + " : " + response.getStatus.code + " " + response.content.toString(Config.xitrum.request.charset))
  }
}

@GET("sync")
class SyncAction extends Action with MyFilter {
  def execute(){
    NotModified.setNoClientCache(response)
    logging("Sync action begin of execute")
    logging("Sync action before respondText")
    respondText("SYNC")
    .addListener(new ChannelFutureListener {
      def operationComplete(f: ChannelFuture) {
        logging("Sync action complete respondText")
      }
    })
    logging("Sync action after respondText")
    logging("Sync action end of execute")
  }
}

@GET("async")
class ASyncAction extends Action with MyFilter {
  def execute(){
    NotModified.setNoClientCache(response)
    logging("Async action begin of execute")
    val f = Future {
      Thread.sleep(1000)
      0
    }
    f.onSuccess{ case _ =>
      logging("Async action before respondText")
      respondText("ASYNC")
      .addListener(new ChannelFutureListener {
        def operationComplete(f: ChannelFuture) {
          logging("Async action complete respondText ")
        }
      })
      logging("Async action after respondText ")
    }
    logging("Async action end of execute ")
  }
}

@GET("syncActor")
class SyncActorAction extends ActorAction with MyFilter {
  def execute(){
    NotModified.setNoClientCache(response)
    logging("Sync actor action begin of execute")
    logging("Sync actor action before respondText")
    respondText("SYNC")
    .addListener(new ChannelFutureListener {
      def operationComplete(f: ChannelFuture) {
        logging("Sync actor action complete respondText")
      }
    })
    logging("Sync actor action after respondText")
    logging("Sync actor action end of execute")
  }
}

@GET("asyncActor")
class ASyncActorAction extends ActorAction with MyFilter {
  def execute(){
    NotModified.setNoClientCache(response)
    logging("Async actor action begin of execute")
    val f = Future {
      Thread.sleep(1000)
      0
    }
    f.onSuccess{ case _ =>
      logging("Async actor action before respondText")
      respondText("ASYNC")
      .addListener(new ChannelFutureListener {
        def operationComplete(f: ChannelFuture) {
          logging("Async actor action complete respondText ")
        }
      })
      logging("Async actor action after respondText ")
    }
    logging("Async actor action end of execute ")
  }
}

@GET("syncFuture")
class SyncFutureAction extends FutureAction with MyFilter {
  def execute(){
    NotModified.setNoClientCache(response)
    logging("Sync future action begin of execute")
    logging("Sync future action before respondText")
    respondText("SYNC")
    .addListener(new ChannelFutureListener {
      def operationComplete(f: ChannelFuture) {
        logging("Sync future action complete respondText")
      }
    })
    logging("Sync future action after respondText")
    logging("Sync future action end of execute")
  }
}

@GET("asyncFuture")
class ASyncFutureAction extends FutureAction with MyFilter {
  def execute(){
    NotModified.setNoClientCache(response)
    logging("Async future action begin of execute")
    val f = Future {
      Thread.sleep(1000)
      0
    }
    f.onSuccess{ case _ =>
      logging("Async future action before respondText")
      respondText("ASYNC")
      .addListener(new ChannelFutureListener {
        def operationComplete(f: ChannelFuture) {
          logging("Async future action complete respondText ")
        }
      })
      logging("Async future action after respondText ")
    }
    logging("Async future action end of execute ")
  }
}