OAuth           = require('oauth').OAuth
_               = require 'underscore'

class LinkedInClient

  @baseUrl:                   'https://api.linkedin.com'
  @requestTokenUrl:           "#{@baseUrl}/uas/oauth/requestToken"
  @accessTokenUrl:            "#{@baseUrl}/uas/oauth/accessToken"
  @authorizeUrl:              "#{@baseUrl}/uas/oauth/authorize"  
  @profileFields:             ['id', 'headline', 'first-name', 'last-name', 'public-profile-url', 'picture-url', 'educations', 'positions', 'email-address']    
  @groupFields:               ['id', 'type', 'category', 'creator', 'title', 'summary', 'creation-time', 'likes', 'comments']    

  keys:
    apiKey:                   null
    apiSecret:                null
    
  tokens:  
    oauthAccessToken:         null
    oauthAccessTokenSecret:   null
    oauthRequestToken:        null
    oauthRequestTokenSecret:  null
       
  constructor: (@keys, @tokens) ->
  
  generateOAuth: (callbackUrl) ->
    @oauth = new OAuth LinkedInClient.requestTokenUrl,
                       LinkedInClient.accessTokenUrl,
                       @keys.apiKey,
                       @keys.apiSecret,
                       '1.0', 
                       callbackUrl, 
                       'HMAC-SHA1', 
                       null, 
                       {"Accept" : "*/*", "Connection" : "close", "User-Agent" : "Node authentication", "x-li-format" : "json"}  
  
  hasAccessToken: ->
   @tokens.oauthAccessToken && @tokens.oauthAccessTokenSecret  
  
  hasRequestToken: ->
   @tokens.oauthRequestToken && @tokens.oauthRequestTokenSecret  
     
  getRequestToken: (redirectUrl, callback) ->
    @generateOAuth redirectUrl
    @oauth.getOAuthRequestToken (error, oauthRequestToken, oauthRequestTokenSecret, results) =>      
      @tokens.oauthRequestToken = oauthRequestToken
      @tokens.oauthRequestTokenSecret = oauthRequestTokenSecret
      callback error, "#{LinkedInClient.authorizeUrl}?oauth_token=#{oauthRequestToken}"
  
  getAccessToken: (oauthVerifier, callback) ->
    throw "Does not have a request token" unless @hasRequestToken()
    @generateOAuth()   
    @oauth.getOAuthAccessToken @tokens.oauthRequestToken, @tokens.oauthRequestTokenSecret, oauthVerifier, (error, oauthAccessToken, oauthAccessTokenSecret) =>
      @tokens.oauthAccessToken = oauthAccessToken
      @tokens.oauthAccessTokenSecret = oauthAccessTokenSecret
      callback error    
  
  getProfile: (callback, id = '~') ->
    throw "Does not have an access token" unless @hasAccessToken()    
    @generateOAuth()
    @oauth.getProtectedResource "#{LinkedInClient.baseUrl}/v1/people/#{id}:(#{LinkedInClient.profileFields.join(',')})", 'GET', @tokens.oauthAccessToken, @tokens.oauthAccessTokenSecret, (error, data, response) =>
      callback error, if error then null else JSON.parse(data)
      
exports.LinkedInClient = LinkedInClient