/* minimal couch in node
 *
 * copyright 2011 nuno job <nunojob.com> (oO)--',--
 *
 * licensed under the apache license, version 2.0 (the "license");
 * you may not use this file except in compliance with the license.
 * you may obtain a copy of the license at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * unless required by applicable law or agreed to in writing, software
 * distributed under the license is distributed on an "as is" basis,
 * without warranties or conditions of any kind, either express or implied.
 * see the license for the specific language governing permissions and
 * limitations under the license.
 */
var request     = require('request')
  , fs          = require('fs')
  , qs          = require('querystring')
  , u           = require('url')
  , error       = require('./error')
  , nano
  ;

function isEmpty(object) {
  for(var property in object) {
    if(object.hasOwnProperty(property)) return false; }
  return true;
}

/*
 * nano is a library that helps you building requests to couchdb
 * that is built on top of mikeal/request
 *
 * no more, no less
 * be creative. be silly. have fun! relax (and don't forget to compact).
 *
 * dinosaurs spaceships!
 */
module.exports = exports = nano = function database_module(cfg) {
  var public_functions = {}
    , request_opts     = {}
    , logging
    , path
    , path_array
    , db
    , auth
    , port
    ;

 /****************************************************************************
  * relax                                                                    *
  ***************************************************************************/
 /*
  * relax
  *
  * base for all request using nano
  * this function assumes familiarity with the couchdb api
  *
  * e.g.
  * nano.request( { db: "alice"
  *               , doc: "rabbit"
  *               , method: "GET"
  *               , params: { rev: "1-967a00dff5e02add41819138abb3284d"}
  *               },
  *   function (_,b) { console.log(b) });
  *
  * @error {request:socket} problem connecting to couchdb
  * @error {couch:*} an error proxied from couchdb
  *
  * @param {opts:object|string} request options; 
  *          e.g. {db: "test", method: "GET"}
  *        {opts.db:string} database name
  *        {opts.method:string:optional} http method, defaults to "GET"
  *        {opts.path:string:optional} a full path, override `doc` and `att`
  *        {opts.doc:string:optional} document name
  *        {opts.att:string:optional} attachment name
  *        {opts.content_type:string:optional} content type, default to json
  *        {opts.body:object|string|binary:optional} document or attachment body
  *        {opts.encoding:string:optional} encoding for attachments
  * @param {callback:function:optional} function to call back
  */
  function relax(opts,callback) {
    if(typeof opts === 'string') { opts = {path: opts}; }
    var log = logging();
    var headers = { "content-type": "application/json"
                  , "accept"      : "application/json"
                  }
      , req     = { method : (opts.method || "GET")
                  , headers: headers
                  , uri    : cfg.url }
      , params  = opts.params
      , status_code
      , parsed
      , rh
      ;

    if (opts.jar) { req.jar = opts.jar; }
    if(opts.db) { req.uri += "/" + opts.db; }
    if(opts.path) { req.uri += "/" + opts.path; }
    else if(opts.doc)  {
      if(!/^_design/.test(opts.doc)) {
        try { req.uri += "/" + encodeURIComponent(opts.doc); }
        catch (ex1) {
          ex1.message = 'couldnt encode: ' + opts.doc + ' as an uri';
          return error.request_err(ex, 'encodeuri', {});
        }
      }
      else {
        req.uri += "/" + opts.doc;
      }
      if(opts.att) { req.uri += "/" + opts.att; }
    }
    if(opts.encoding && callback) {
      req.encoding = opts.encoding;
      delete req.headers["content-type"];
      delete req.headers.accept;
    }
    if(opts.content_type) {
      req.headers["content-type"] = opts.content_type;
      delete req.headers.accept; // undo headers set
    }
    if(!isEmpty(params)) {
      ['startkey', 'endkey', 'key', 'keys'].forEach(function (key) {
        if (key in params) {
          try { params[key] = JSON.stringify(params[key]); }
          catch (ex2) { 
            ex2.message = 'bad params: ' + key + ' = ' + params[key];
            return error.request_err(ex, 'jsonstringify', {}); 
          }
        }
      });
      try { req.uri += "?" + qs.stringify(params); }
      catch (ex3) {
        ex3.message = 'invalid params: ' + params.toString();
        return error.request_err(ex3, 'qsstringify', {});
      }
    }
    if(!callback) { // void callback, stream
      try {
        return request(req);
      } catch (ex4) { 
        return error.request_err(ex4, 'streamthrow', {});
      }
    }
    if(opts.body) {
      if (Buffer.isBuffer(opts.body)) {
        req.body = opts.body; // raw data
      }
      else {
        try {
          req.body = JSON.stringify(opts.body);
        } catch (ex5) { 
          ex5.message = "couldn't json.stringify the body you provided";
          return error.request_err(ex5, 'jsonstringify', {}, callback);
        }
      } // json data
    }
    log(req);
    try {
      var stream = request(req, function(e,h,b){
        rh = (h && h.headers || {});
        rh['status-code'] = status_code = (h && h.statusCode || 500);
        rh.uri            = req.uri;
        if(e) {
          log({err: 'socket', body: b, headers: rh });
          callback(error.request(e,"socket",req,status_code),b,rh);
          return stream;
        }
        delete rh.server;
        delete rh['content-length'];
        try { parsed = JSON.parse(b); } catch (err) { parsed = b; }
        if (status_code >= 200 && status_code < 300) {
          log({err: null, body: parsed, headers: rh});
          callback(null,parsed,rh);
          return stream;
        }
        else { // proxy the error directly from couchdb
          log({err: 'couch', body: parsed, headers: rh});
          if (!parsed) { parsed = {}; }
          callback(error.couch(parsed.reason,parsed.error,req,status_code),
            parsed, rh);
          return stream;
        }
      });
      return stream;
    } catch(ex6) { 
      return error.request_err(ex6, 'callbackthrow', {});
    }
  }

 /****************************************************************************
  * db                                                                       *
  ***************************************************************************/
 /*
  * creates a couchdb database
  * http://wiki.apache.org/couchdb/HTTP_database_API
  *
  * e.g. function recursive_retries_create_db(tried,callback) {
  *        nano.db.create(db_name, function (e,b) {
  *          if(tried.tried === tried.max_retries) {
  *            callback("Retries work");
  *            return;
  *          }
  *          else {
  *            tried.tried += 1;
  *            recursive_retries_create_db(tried,callback);
  *          }
  *        });
  *      }
  *
  * @param {db_name:string} database name
  *
  * @see relax
  */
  function create_db(db_name, callback) {
    return relax({db: db_name, method: "PUT"},callback);
  }

 /*
  * annihilates a couchdb database
  *
  * e.g. nano.db.destroy(db_name);
  *
  * even though this examples looks sync it is an async function
  *
  * @param {db_name:string} database name
  *
  * @see relax
  */
  function destroy_db(db_name, callback) {
    return relax({db: db_name, method: "DELETE"},callback);
  }

 /*
  * gets information about a couchdb database
  *
  * e.g. nano.db.get(db_name, function(e,b) {
  *        console.log(b);
  *      });
  *
  * @param {db_name:string} database name
  *
  * @see relax
  */
  function get_db(db_name, callback) {
    return relax({db: db_name, method: "GET"},callback);
  }

 /*
  * lists all the databases in couchdb
  *
  * e.g. nano.db.list(function(e,b) {
  *        console.log(b);
  *      });
  *
  * @see relax
  */
  function list_dbs(callback) {
    return relax({db: "_all_dbs", method: "GET"},callback);
  }

 /*
  * compacts a couchdb database
  *
  * e.g. nano.db.compact(db_name);
  *
  * @param {db_name:string} database name
  * @param {design_name:string:optional} design document name
  *
  * @see relax
  */
  function compact_db(db_name, design_name, callback) {
    if(typeof design_name === "function") {
      callback = design_name;
      design_name = null;
    }
    return relax({db: db_name, doc: "_compact", att: design_name, method: "POST"},callback);
  }

 /*
  * couchdb database _changes feed
  *
  * e.g. nano.db.changes(db_name, {since: 2}, function (e,r,h) {
  *        console.log(r);
  *      });
  *
  * @param {db_name:string} database name
  * @param {params:object:optional} additions to the querystring
  *
  * @see relax
  */
  function changes_db(db_name, params, callback) {
    if(typeof params === "function") {
      callback = params;
      params = {};
    }
    return relax({db: db_name, path: "_changes", params: params, method: "GET"},callback);
  }

 /*
  * replicates a couchdb database
  *
  * e.g. nano.db.replicate(db_1, db_2);
  *
  * @param {source:string} name of the source database
  * @param {target:string} name of the target database
  * @param {continuous:bool:optional} continuous replication on?
  *
  * @see relax
  */
  function replicate_db(source, target, continuous, callback) {
    if(typeof continuous === "function") {
      callback   = continuous;
      continuous = false;
    }
    var body = {source: source, target: target};
    if(continuous) { body.continuous = true; }
    return relax({db: "_replicate", body: body, method: "POST"},callback);
  }

 /****************************************************************************
  * doc                                                                      *
  ***************************************************************************/
  function document_module(db_name) {
    var public_functions = {};

   /*
    * inserts a document in a couchdb database
    * http://wiki.apache.org/couchdb/HTTP_Document_API
    *
    * @param {doc:object|string} document body
    * @param {doc_name:string:optional} document name
    *
    * @see relax
    */
    function insert_doc(doc,doc_name,callback) {
      var opts = {db: db_name, body: doc, method: "POST"};
      if(doc_name) {
        if(typeof doc_name === "function") {
          callback = doc_name;
        }
        else {
          opts.doc = doc_name;
          opts.method = "PUT";
        }
      }
      return relax(opts,callback);
    }

   /*
    * destroy a document from a couchdb database
    *
    * @param {doc_name:string} document name
    * @param {rev:string} previous document revision
    *
    * @see relax
    */
    function destroy_doc(doc_name,rev,callback) {
      return relax({db: db_name, doc: doc_name, method: "DELETE", params: {rev: rev}},
        callback);
    }

   /*
    * get a document from a couchdb database
    *
    * e.g. db2.get("foo", {revs_info: true}, function (e,b,h) {
    *        console.log(e,b,h);
    *        return;
    *      });
    *
    * @param {doc_name:string} document name
    * @param {params:object:optional} additions to the querystring
    *
    * @see relax
    */
    function get_doc(doc_name,params,callback) {
      if(typeof params === "function") {
        callback = params;
        params   = {};
      }
      return relax({db: db_name, doc: doc_name, method: "GET", params: params},callback);
    }

   /*
    * lists all the documents in a couchdb database
    *
    * @param {params:object:optional} additions to the querystring
    *
    * @see get_doc
    * @see relax
    */
    function list_docs(params,callback) {
      if(typeof params === "function") {
        callback = params;
        params   = {};
      }
      return relax({db: db_name, path: "_all_docs", method: "GET", params: params},callback);
    }

   /*
    * bulk fetch functionality
    * [1]: http://wiki.apache.org/couchdb/HTTP_Bulk_Document_API
    *
    * @param {doc_names:object} document keys as per the couchdb api[1]
    * @param {params:object} additions to the querystring, note that include_docs is always set to true
    *
    * @see get_doc
    * @see relax
    */
    function fetch_docs(doc_names,params,callback) {
      if(typeof params === "function") {
        callback = params;
        params   = {};
      }
      params.include_docs = true;
      return relax({db: db_name, path: "_all_docs", method: "POST", params: params, body: doc_names},callback);
    }

   /*
    * calls a view
    *
    * @param {design_name:string} design document name
    * @param {view_name:string} view to call
    * @param {params:object:optional} additions to the querystring
    *
    * @see relax
    */
    function view_docs(design_name,view_name,params,callback) {
      if(typeof params === "function") {
        callback = params;
        params   = {};
      }
      var view_path = '_design/' + design_name + '/_view/'  + view_name;
      if (params.keys) {
        var body = {keys: params.keys};
        delete params.keys;
        return relax({db: db_name, path: view_path
                     , method: "POST", params: params, body: body}, callback);
      }
      else {
        return relax({db: db_name, path: view_path
                     , method: "GET", params: params},callback);
      }
    }

   /*
    * calls document update handler design document
    *
    *
    * @param {design_name:string} design document namd
    * @param {update_name:string} update method to call
    * @param {doc_name:string} document name to update
    * @param {params:object} additions to the querystring
   */
   function update_with_handler_doc(design_name, update_name, 
     doc_name, params, callback) {
     if(typeof params === "function") {
       callback = params;
       params   = {};
     }
     var update_path = '_design/' + design_name + '/_update/' + 
       update_name + '/' + doc_name;
     return relax(
       { db: db_name, path: update_path, method: "PUT"
       , params: params }, callback);
   }

   /*
    * bulk update/delete/insert functionality
    * [1]: http://wiki.apache.org/couchdb/HTTP_Bulk_Document_API
    *
    * @param {docs:object} documents as per the couchdb api[1]
    * @param {params:object} additions to the querystring
    *
    * @see get_doc
    * @see relax
    */
    function bulk_docs(docs,params,callback) {
     if(typeof params === "function") {
       callback = params;
       params = {};
     }
     return relax(
       { db: db_name, path: "_bulk_docs", body: docs
       , method: "POST", params: params}, callback);
    }

   /**************************************************************************
    * attachment                                                             *
    *************************************************************************/
   /*
    * inserting an attachment
    * [2]: http://wiki.apache.org/couchdb/HTTP_Document_API
    *
    * e.g.
    * db.attachment.insert("new", "att", buffer, "image/bmp", {rev: b.rev},
    *   function(_,response) {
    *     console.log(response);
    * });
    *
    * don't forget that params.rev is required in most cases. only exception
    * is when creating a new document with a new attachment. consult [2] for
    * details
    *
    * @param {doc_name:string} document name
    * @param {att_name:string} attachment name
    * @param {att:buffer} attachment data
    * @param {content_type:string} attachment content-type
    * @param {params:object:optional} additions to the querystring
    *
    * @see relax
    */
    function insert_att(doc_name,att_name,att,content_type,params,callback) {
      if(typeof params === "function") {
        callback = params;
        params   = {};
      }
      return relax(
        { db: db_name, att: att_name, method: "PUT"
        , content_type: content_type, doc: doc_name, params: params
        , body: att}, callback);
    }

   /*
    * get an attachment
    *
    * @param {doc_name:string} document name
    * @param {att_name:string} attachment name
    * @param {params:object:optional} additions to the querystring
    *
    * @see relax
    */
    function get_att(doc_name,att_name,params,callback) {
      if(typeof params === "function") {
        callback = params;
        params   = {};
      }
      return relax({ db: db_name, att: att_name, method: "GET", doc: doc_name
                   , params: params, encoding: "binary"},callback);
    }

   /*
    * destroy an attachment
    *
    * @param {doc_name:string} document name
    * @param {att_name:string} attachment name
    * @param {rev:string} previous document revision
    *
    * @see relax
    */
    function destroy_att(doc_name,att_name,rev,callback) {
      return relax({ db: db_name, att: att_name, method: "DELETE"
                  , doc: doc_name, params: {rev: rev}},callback);
    }

    public_functions = { info: function(cb) { return get_db(db_name,cb); }
                       , replicate: function(target,continuous,cb) {
                           if(typeof continuous === "function") {
                             cb         = continuous;
                             continuous = false;
                           }
                           return replicate_db(db_name,target,continuous,cb);
                         }
                       , compact: function(cb) { 
                           return compact_db(db_name,cb); 
                         }
                       , changes: function(params,cb) {
                           return changes_db(db_name,params,cb);
                         }
                       , insert: insert_doc
                       , get: get_doc
                       , destroy: destroy_doc
                       , bulk: bulk_docs
                       , list: list_docs
                       , fetch: fetch_docs
                       , config: {url: cfg.url, db: db_name}
                       , attachment: { insert: insert_att
                                     , get: get_att
                                     , destroy: destroy_att
                                     }
                       , updateWithHandler: update_with_handler_doc
                       };
    public_functions.view = view_docs;
    public_functions.view.compact = function(design_name,cb) {
      return compact_db(db_name,design_name,cb);
    };
    return public_functions;
  }

  public_functions = { db:  { create: create_db
                            , get: get_db
                            , destroy: destroy_db
                            , list: list_dbs
                            , use: document_module   // alias
                            , scope: document_module // alias
                            , compact: compact_db
                            , replicate: replicate_db
                            , changes: changes_db
                            }
                     , use: document_module
                     , scope: document_module        // alias
                     , request: relax
                     , relax: relax                  // alias
                     , dinosaur: relax               // alias
                     };

  if(typeof cfg === "string") {
    if(/^https?:/.test(cfg)) { cfg = {url: cfg}; } // url
    else {
      try { cfg   = require(cfg); } // file path
      catch(e) {
        e.message = "couldn't read config file " + 
          (cfg ? cfg.toString() : '');
        throw error.init(e, "badfile");
      }
    }
  }
  
  if(!(cfg && cfg.url))
    throw error.init("no configuration with a valid url was given", "badurl");

  public_functions.config = cfg;

  if(cfg.proxy || cfg.jar) {
    if(cfg.proxy) 
      request_opts.proxy = cfg.proxy;
    request_opts.jar     = !!cfg.jar;
    request              = require('request').defaults(request_opts);
  }
  
  // assuming a cfg.log inside cfg
  logging = require('./logging')(cfg);
  
  try { 
    path       = u.parse(cfg.url);
    path_array = path.pathname.split('/').filter(function(e) { return e; });
  }
  catch (e2) {
    e2.message = "your url is invalid: " + cfg.url;
    throw error.init(e2, "invalidurl");
  }
  
  // nano('http://couch.nodejitsu.com/db1') should return a database
  // nano('http://couch.nodejitsu.com')     should return a nano object
  if(path.pathname && path_array.length > 0) {
    auth    = path.auth ? path.auth + '@' : '';
    port    = path.port ? ':' + path.port : '';
    db      = path_array[0];
    cfg.url = u.format(
      {protocol:path.protocol,host: auth + path.hostname + port});
    return document_module(db);
  }
  else   { return public_functions; }

};

/*
 * and now an ascii dinosaur
 *              _
 *            / _) ROAR! i'm a vegan!
 *     .-^^^-/ /
 *  __/       /
 * /__.|_|-|_|
 *
 * thanks for visiting! come again!
 *
 * LH1059-A321
 * LH1178-A321
 */

nano.version = JSON.parse(
  fs.readFileSync(__dirname + "/package.json")).version;
nano.path    = __dirname;