             redirect_uri: string - The callback URL that the user will return to after authorization (required)
             scope: PersonalScope - Object representing the scope for which you are requesting authorization (required)
             update: boolean - specifies if the selection UI dialog should be presented even if the 3rd party already has access to the requested resource(default: true)
-            sandbox: boolean - uses sandbox if true, production otherwise (default: false)
-
-        returns a url object, call url.format(<return value>) to get formatted URL string (see http://nodejs.org/api/url.html) 
+
+        returns an object containing
+            url: string - a formatted URL string (same formatted output as url.format() - see http://nodejs.org/api/url.html) 
+            state: the state parameter in the redirect_uri
         ###
 
         #add state param to redirect uri for the securitys

# MIT License
###

crypto = require "crypto"

class PersonalApp
    ###
    PersonalApp is the central class to the library.  Instantiate it to access the Personal API.
    ###
    
    constructor: (@config) ->
        ###
        config:
            client_id: string - <client id> (required)
            client_secret: string - <client secret> (required)
        ###
        @_state = {}
        @_access = {}
    
    get_auth_request_url: (options) ->
        ###

        ###
        return @to_s()

#Stuff for the connect/express use case
connect_opts = 
    update: true
    sandbox: false

connect_curr_req_url = do ->
    _url = "init_val"
    ret_val = 
        get: -> return _url
        set: (new_url) -> _url = new_url

PersonalConnectOptions = (options) ->
    ###
    #Add all options to the connect/express options for the Personal library
    #
    #options:
    #   client_id:
    #   client_secret:
    #   scope:
    #   update: 
    #   sandbox:
    ###
    connect_opts[key] = val for key,val of options

PersonalHelpers = (app) ->
    app.locals
        auth_req_url: -> return connect_curr_req_url.get()
            
PersonalMiddleware = (req, res, next) ->
    #put logout fn in the request
    req.personal =
        logout: () ->
            req.session?.personal = logged_in: false
    
    #check that we have session and init it
    return next(new Error "session middleware not loaded") if not req.session? 
    req.session.personal = {} if not req.session.personal?
    req.personal.logout() if not req.personal?
    sess = req.session.personal

    #we already have a valid session
    if sess.access_token? and sess.refresh_token? and sess.expiration?
        req.personal.logged_in = true
        req.personal.client = new PersonalClient
            access_token: sess.access_token
            refresh_token: sess.refresh_token
            expiration: sess.expiration
        return next()
    app = new PersonalApp connect_opts

    #we are at the callback url
    if req.query.code? and req.query.state? and req.query.personal?
        if sess.state? and sess.state == req.query.state and sess.redirect_uri?
            #do access token stuff
            promise = app.get_access_token_auth
                code: req.query.code
                state: req.query.state
                redirect_url: sess.redirect_url
            promise.then (access_obj) ->
                sess[key] = val for key,val of access_obj
                sess.client = new PersonalClient access_obj
                next()
            ,(err) ->
                next(err)
            return
    
    #we need to create the url for login and auth
    new_redir_uri = url.parse "#{req.protocol}://#{req.headers.host}#{req.url}", true
    new_redir_uri.search = ""
    new_redir_uri.query.personal = true
    auth_req_obj = app.get_auth_request_url
        scope: connect_opts.scope
        update: connect_opts.update
        sandbox: connect_opts.sandbox
        redirect_uri: url.format new_redir_uri
    connect_curr_req_url.set auth_req_obj.url
    #    console.log connect_curr_req
    sess.state = auth_req_obj.state
    sess.redirect_uri = auth_req_obj.redirect_uri
    next()

#export stuff
exports.Options = PersonalConnectOptions
exports.Helpers = PersonalHelpers
exports.Middleware = PersonalMiddleware
exports.App = PersonalApp
exports.Scope = PersonalScope
