


############################################################################################################
USERDB                    = require 'coffeenode-userdb'
OPTIONS                   = require 'coffeenode-options'
TRM                       = require 'coffeenode-trm'
rpr                       = TRM.rpr.bind TRM
badge                     = 'α1/templates'
log                       = TRM.get_logger 'plain',     badge
info                      = TRM.get_logger 'info',      badge
whisper                   = TRM.get_logger 'whisper',   badge
alert                     = TRM.get_logger 'alert',     badge
debug                     = TRM.get_logger 'debug',     badge
warn                      = TRM.get_logger 'warn',      badge
help                      = TRM.get_logger 'help',      badge
BITSNPIECES               = require 'coffeenode-bitsnpieces'
#...........................................................................................................
TEACUP                    = require 'coffeenode-teacup'
#...........................................................................................................
app_info                  = OPTIONS.get_app_info()
app_key                   = app_info[ 'name' ]
#...........................................................................................................
A1                        = require './main'
user_db                   = USERDB.new_db()
#...........................................................................................................
USERDB.validate_is_running user_db


#===========================================================================================================
# TEACUP NAMESPACE ACQUISITION
#-----------------------------------------------------------------------------------------------------------
for name_ of TEACUP
  eval "#{name_} = TEACUP[ #{rpr name_} ]"


#===========================================================================================================
# LAYOUT
#-----------------------------------------------------------------------------------------------------------
# TEMPLATES = {}
@layout = ( request, response, content, done ) ->
  log TRM.blue 'layout'
  return @[ request[ 'A1' ]?[ 'layout' ] ? 'plain' ] request, response, content, done

#-----------------------------------------------------------------------------------------------------------
@plain = ( request, response, content, done ) ->
  log TRM.blue 'plain'
  O             = request[ 'A1'  ]
  page_style    = O[ 'page-style'   ] ? 'plain'
  title         = O[ 'title'        ] ? 'welcome'
  session       = request[ 'session' ]
  has_session   = session?
  if has_session
    user        = session[ 'user' ]
    logged_in   = user?
  else
    user        = null
    logged_in   = no
  #.........................................................................................................
  return render =>
    DOCTYPE 5
    HTML =>
      #.....................................................................................................
      HEAD =>
        COMMENT '#head-top'
        META charset: 'utf-8'
        TITLE title
        RAW '<!--[if lt IE 9]>'
        SCRIPT src: '/common/jquery.com/jquery-1.10.2.js'
        RAW '<![endif]--><!--[if gte IE 9]><!-->'
        SCRIPT src: '/common/jquery.com/jquery-2.0.3.js'
        RAW '<!--<![endif]-->'

        #===================================================================================================
        # Client-Side Cookies
        #...................................................................................................
        SCRIPT src: '/common/github.com_carhartl_jquery-cookie/jquery.cookie.js'

        #===================================================================================================
        # Notifications
        #...................................................................................................
        ### https://github.com/ehynds/jquery-notify ###
        ### http://www.erichynds.com/blog/a-jquery-ui-growl-ubuntu-notification-widget ###
        SCRIPT src: '/common/jquery.com/jquery-ui-1.10.3/ui/jquery.ui.widget.js'
        SCRIPT src: '/common/erichynds.com/jquery-notify/src/jquery.notify.js'
        LINK rel: 'stylesheet', href: '/common/erichynds.com/jquery-notify/ui.notify.css'
        RAW """
          <style>
            .ui-notify-message h1 {
              font-size:    120%;
              font-weight:  normal;
              font-style:   italic;
              }
            </style>"""
        COFFEESCRIPT ->
          #.................................................................................................
          after = ( seconds, method ) -> setTimeout method, seconds * 1000
          #.................................................................................................
          notification_options =
            sticky: no
            click:  ( event, notification ) -> notification.close()
          #.................................................................................................
          notify = ( title, text ) ->
            message =
              title:  title
              text:   text
            #...............................................................................................
            ( $ '#notify-wrap' ).notify 'create',
              'notify-default'
              message
              notification_options
          #.................................................................................................
          ( $ 'document' ).ready ->
            ################################################################################################
            ( $ '#notify-wrap' ).notify
              speed:    250   # i.e. effect duration
              expires:  5000  # fades out after so many ms
            ################################################################################################
            if ( flash_messages = $.cookie 'flash-messages' )?
              flash_messages = JSON.parse flash_messages
              for idx in [ flash_messages.length - 1 .. 0 ] by -1
                [ title, text, ] = flash_messages[ idx ]
                notify title, text
              flash_messages.length = 0
              $.cookie 'flash-messages', '[]'
            #...............................................................................................
            # after 0.5, -> notify "Attention Y'All", 'the sublime message is talking to you'
            # after 1.5, -> notify "Attention Y'All", 'hear hear'
        #===================================================================================================


        # ( META name: 'description', content: O[ 'description' ] ) if O[ 'description' ]?
        # LINK rel: 'stylesheet', href: '/public/cssnormalize-min.css'
        # LINK rel: 'stylesheet', href: '/public/mingkwai.css'
        # LINK rel: 'stylesheet', href: '/public/font-awesome-4.0.0/css/font-awesome.css'
        LINK rel: 'shortcut icon', href: '/public/favicon.ico?v6'
        # SCRIPT src: '/public/github_com_carhartl_jquery-cookie/jquery.cookie.js'
        # SCRIPT src: '/public/coffeenode-tagtool/main.js'
        # SCRIPT src: '/public/mingkwai.js'



        COMMENT '#head-bottom'
      #.....................................................................................................
      BODY ".#{page_style}", =>
        COMMENT '#body-top'

        #===================================================================================================
        # Notifications
        #...................................................................................................
        # <div id="notify-wrap" style="display: none;"><div id="notify-default"><h1>#{title}</h1><p>#{text}</p></div></div>
        DIV '#notify-wrap', style: 'display: none;', =>
          DIV '#notify-default', =>
            H1 => TEXT '\#{title}'
            P  => TEXT '\#{text}'
        #===================================================================================================
        DIV id: 'login-reminder', =>
          if logged_in
            TEXT "you are logged in as #{request[ 'session' ][ 'user' ]}"
          else
            null
        #...................................................................................................
        RAW content
        if logged_in
          DIV => A href: '/logout', 'log out'
        else
          unless request[ 'url' ] is '/login'
            DIV => A href: '/login', 'log in'
        DIV => A href: '/',             'home'
        DIV => A href: '/restricted',   'restricted'
        DIV => A href: '/welcome',      'welcome'
        DIV => A href: '/goodbye',      'goodbye'
        DIV => A href: '/notfound',     'not found'
        DIV => A href: '/contact',      'contact'
        DIV => A href: '/imprint',      'imprint'
        DIV => A href: '/privacy',      'privacy'
        #...................................................................................................
        COMMENT '#body-bottom'


#===========================================================================================================
# GENERAL VIEWS
#-----------------------------------------------------------------------------------------------------------
@homepage = ( request, response, next ) ->
  log TRM.blue 'homepage'
  O             = request[ 'A1'  ]
  O[ 'title' ]  = 'Homepage for Alpha-One'
  #.........................................................................................................
  return render =>
    H1 'Home'
    DIV "homepage for alpha-one"

#-----------------------------------------------------------------------------------------------------------
@welcome = ( request, response, next ) ->
  log TRM.blue 'welcome'
  O             = request[ 'A1'  ]
  O[ 'title' ]  = 'Welcome!'
  #.........................................................................................................
  return render =>
    H1 'Welcome'
    DIV "welcome to alpha-one"

#-----------------------------------------------------------------------------------------------------------
@goodbye = ( request, response, next ) ->
  log TRM.blue 'goodbye'
  O             = request[ 'A1'  ]
  O[ 'title' ]  = 'Good-Bye'
  #.........................................................................................................
  return render =>
    H1 'Good-Bye'
    DIV "good-bye from alpha-one"

#-----------------------------------------------------------------------------------------------------------
@not_found = ( request, response ) ->
  log TRM.blue 'not_found'
  O             = request[ 'A1'  ]
  O[ 'title' ]  = 'Not Found'
  A1.HTTP.not_found request, response
  #.........................................................................................................
  return render =>
    H1 '404'
    DIV "nothing found for #{request[ 'url' ]}"

#===========================================================================================================
# BOILERPLATE VIEWS
#-----------------------------------------------------------------------------------------------------------
@contact = ( request, response ) ->
  log TRM.blue 'contact'
  O             = request[ 'A1'  ]
  O[ 'title' ]  = 'contact'
  #.........................................................................................................
  return render =>
    H1 'Contact'
    DIV "Contact us at info@example.com"

#-----------------------------------------------------------------------------------------------------------
@imprint = ( request, response ) ->
  log TRM.blue 'imprint'
  O             = request[ 'A1'  ]
  O[ 'title' ]  = 'imprint'
  request[ 'A1' ][ 'flash' ] 'Welcome...', '...to the mighty Alpha-One Imprint page!'
  request[ 'A1' ][ 'flash' ] 'Info', 'We accept pull requests'
  #.........................................................................................................
  return render =>
    H1 'Imprint'
    DIV "The maintainers of this site are somewhat responsible for some content."

#-----------------------------------------------------------------------------------------------------------
@privacy = ( request, response ) ->
  log TRM.blue 'privacy'
  O             = request[ 'A1'  ]
  O[ 'title' ]  = 'privacy'
  #.........................................................................................................
  return render =>
    H1 'Privacy'
    DIV "Yeah, privacy. Well, we take it seriously."


#===========================================================================================================
# LOGIN / LOGOUT VIEWS
#-----------------------------------------------------------------------------------------------------------
### TAINT these things should probably go into their own module, no? ###

#-----------------------------------------------------------------------------------------------------------
@login_get = ( request, response ) ->
  log TRM.blue 'login_get'
  O             = request[ 'A1'  ]
  O[ 'title' ]  = 'Log In or Sign Up'
  comes_from    = request[ 'cookies' ]?[ 'comes-from' ]
  session       = request[ 'session' ]
  has_session   = session?
  #.........................................................................................................
  if has_session
    login_count = session[ 'login-count' ] += 1
  else
    login_count = 0
  #.........................................................................................................
  return render =>
    #.......................................................................................................
    if comes_from?
      request[ 'A1' ][ 'flash' ] 'For your information...', "You must log in to visit #{comes_from}"
    #.......................................................................................................
    if login_count > 1
      DIV "attempt to log in: ##{login_count}"
    #.......................................................................................................
    H1 'Log In or Sign Up'
    DIV =>
      FORM '#login-form', method: 'post', action: '/login', =>
        FIELDSET =>
          LEGEND "Log In"
          DIV => TEXT_INPUT
            label: "Your email or user name:",
            name:       'uid-hint'
            autofocus:  yes
            required:   yes
          DIV => PASSWORD         label: "Your password:"
          DIV => SUBMIT           label: "submit"
    DIV =>
      FORM '#signup-form', method: 'post', action: '/signup', =>
        FIELDSET =>
          LEGEND "Sign Up"
          DIV => EMAIL            label: "Your email:",           autocomplete: 'off'
          DIV => TEXT_INPUT
            label: "Your user name:",
            autocomplete:   'off'
            name:           'name'
            autofocus:      yes
            required:       yes
          DIV => PASSWORD         label: "Your password:",        autocomplete: 'off'
          DIV => CONFIRM_PASSWORD label: "Your password again:",  autocomplete: 'off'
          DIV => SUBMIT           label: "submit"

#-----------------------------------------------------------------------------------------------------------
@login_post = ( request, response, done ) ->
  log TRM.blue 'login_post'
  uid_hint      = request[ 'body' ][ 'uid-hint' ]
  password      = request[ 'body' ][ 'password' ]
  info '©11k', 'query arguments:', request[ 'body' ]
  #.........................................................................................................
  USERDB.authenticate_user user_db, { name: uid_hint, }, password, ( error, user_known, password_matches ) =>
    ### TAINT code duplication ###
    if error?
      if error[ 'message' ] is 'connect ECONNREFUSED'
        alert """\nthe CoffeeNode UserDB specified as \n#{rpr user_db}\ncan not be accessed"""
      else
        alert error
      return done new Error error.stack
    log '©34e', ( TRM.gold uid_hint ), ( TRM.blue password ), ( TRM.truth user_known ), ( TRM.truth password_matches )
    #.......................................................................................................
    if user_known and password_matches
      TRM.dir '©34e', (require 'express').session
      ### TAINT what to do if request.session does not exist? ###
      request.session.regenerate =>
        request.session.user = uid_hint
        # log TRM.lime '©15z', response.headerSent # if response.headerSent?
        A1.HTTP.back_to request, response, '/welcome'
        request.session[ 'just-logged-in' ] = yes
        message = "You have been logged in as user #{rpr uid_hint}"
        request[ 'A1' ][ 'flash' ] "Welcome", message
        done message
    #.......................................................................................................
    else
      log TRM.lime '©15z', response.headerSent # if response.headerSent?
      A1.HTTP.redirect request, response, '/login'
      message = "Your ID #{rpr uid_hint} or password did not match; please try again."
      request[ 'A1' ][ 'flash' ] "Login failed", message
      done message
  return null

#-----------------------------------------------------------------------------------------------------------
@signup_post = ( request, response, done ) ->
  log TRM.blue 'signup_post'
  email         = request[ 'body' ][ 'email'      ]
  name          = request[ 'body' ][ 'name'      ]
  password      = request[ 'body' ][ 'password'   ]
  password_r    = request[ 'body' ][ 'password-r' ]
  #.........................................................................................................
  unless password is password_r
    message = "your passwords do not match"
    A1.HTTP.redirect request, response, '/login'
    done message
  #.........................................................................................................
  ### TAINT check for password strength (maybe only on client) ###
  ### TAINT check for email plausibility ###
  ### TAINT check for email uniqueness ###
  ### TAINT think up a UID generation method ###
  entry =
    'name':       name
    'uid':        "#{email}-#{1 * new Date()}" # placeholder for a better method
    'password':   password
    'email':      email
  #.........................................................................................................
  USERDB.create_user user_db, entry, ( error, result ) ->
    ### TAINT code duplication ###
    if error?
      if error[ 'message' ] is 'connect ECONNREFUSED'
        alert """\nthe CoffeeNode UserDB specified as \n#{rpr user_db}\ncan not be accessed"""
      else
        alert error
      return done new Error error.stack
    #.......................................................................................................
    ### TAINT what to do if request.session does not exist? ###
    request.session.regenerate =>
      request.session.user = entry[ 'uid' ]
      message = "you have been registered as #{entry[ 'uid' ]}"
      request[ 'A1' ][ 'flash' ] "Welcome", message
      A1.HTTP.back_to request, response, '/welcome-new-user'
      done message
  #.........................................................................................................
  return null

#-----------------------------------------------------------------------------------------------------------
@logout = ( request, response, done ) ->
  log TRM.blue 'restricted'
  request.session.destroy =>
    A1.HTTP.back_to request, response, '/goodbye'
    done "You have been logged out."
  #.........................................................................................................
  return null


#===========================================================================================================
# RESCTRICTED VIEWS
#-----------------------------------------------------------------------------------------------------------
@restricted = ( request, response ) ->
  log TRM.blue 'restricted'
  O             = request[ 'A1'  ]
  O[ 'title' ]  = 'Restricted Area'
  uid           = request.session.user
  #.........................................................................................................
  return render =>
    H1 'Restricted Area'
    DIV "This is the Restricted Area"

