
var request = require('request')
try {
  var debug = require('request-debug')
} catch (e) {
  var debug = function () {}
}

var utils = require('./utils')
  , config = require('./config')
  , Query = require('./query')
  , Url = require('./url')
var Options = require('./options').Options
  , Before = require('./options').Before
var providers = require('../config/providers')
  , override = require('../config/override')


function Provider (options) {
  if (!options || !options.provider)
    throw new Error('Purest: provider option is required!')

  config.extend(providers, options.config)
  var provider = providers[options.provider]
  if (!provider) {
    throw new Error('Purest: non existing provider!')
  }

  this.key = options.consumerKey||options.key||null
  this.secret = options.consumerSecret||options.secret||null
  if (provider.__provider) {
    this.oauth = provider.__provider.oauth
    this.oauth2 = provider.__provider.oauth2
  }

  this._request = request.defaults(options.defaults||{})
  options.debug && debug(this._request)
  // url modifiers
  this.domain = options.domain||''
  this.path = options.path||''
  this.version = options.version||''
  this.type = options.type||'json'

  this.apis = config.aliases(provider)||null
  if (options.api && (!this.apis || !this.apis[options.api])) {
    throw new Error('Purest: non existing API!')
  }
  this.api = options.api||'__default'

  this.name = options.provider
  this[options.provider] = true

  this.options = new Options(this)
  this.before = new Before(this)
  this.url = new Url(this)
  // override
  if (override[this.name]) {
    override[this.name].call(this)
  }
}

function prepare (method, uri, options, callback) {
  var params = request.initParams(uri, options, callback)
  var endpoint = params.uri,
    options = params,
    callback = params.callback

  options.method = options.method||(method=='del'?'delete':method).toUpperCase()
  if (method != 'put') {
    options.json = (options.json == undefined) ? true : options.json
  }

  this.oauth && options.oauth && this.options.oauth(options)
  options = config.options(endpoint, options, method, this.apis[options.api||this.api].endpoints)
  this.before.all(endpoint, options)
  this.before[method](endpoint, options)

  return this._request(
    endpoint.indexOf('http') == -1 ? this.url.get(endpoint, options) : endpoint,
    options,
    callback && utils.response(callback))
}

Provider.prototype.get = function (uri, options, callback) {
  return prepare.call(this, 'get', uri, options, callback)
}

Provider.prototype.post = function (uri, options, callback) {
  return prepare.call(this, 'post', uri, options, callback)
}

Provider.prototype.put = function (uri, options, callback) {
  return prepare.call(this, 'put', uri, options, callback)
}

Provider.prototype.del = function (uri, options, callback) {
  return prepare.call(this, 'del', uri, options, callback)
}

Provider.prototype.patch = function (uri, options, callback) {
  return prepare.call(this, 'patch', uri, options, callback)
}

Provider.prototype.head = function (uri, options, callback) {
  return prepare.call(this, 'head', uri, options, callback)
}


Provider.prototype.config = function (name) {
  return new Query(this, name)
}

Provider.prototype.query = function (name) {
  return new Query(this, name)
}

Provider.request = request
exports = module.exports = Provider

@@ -1644,16 +1644,78 @@
 is)%0A  %7D%0A
+  if (options.override) %7B%0A    options.override.call(this)%0A  %7D%0A
 %7D%0A%0Afunct

Add override option in ctor