request = require 'request'

class REST
	constructor: (model) ->
		@url = model::url
		@parse = model::parse if model::parse instanceof Function
		@headers = @fields = @qs = {}
		if model::request
			@headers = model::request.headers if model::request.headers
			@fields = model::request.fields if model::request.fields
			@qs = model::request.qs if model::request.qs
		@keys = []
		@primaryKey = 'id'
		Object.keys(model::keys).forEach (key) =>
			@keys.push key
			@primaryKey = key if model::keys[key].primary
	
	parse: (response) ->
		JSON.parse response
	
	find: (options, done) ->
		return @findByPrimaryKey(options[@primaryKey], done) if options[@primaryKey]
		
		request
			url: "#{ @url }/"
			method: 'GET'
			headers: @headers
			qs: @qs
		, (err, res, body) =>
			response = @parse body
			done err, response if done
	
	findByPrimaryKey: (value, done) ->
		request
			url: "#{ @url }/#{ value }"
			method: 'GET'
			headers: @headers
			qs: @qs
		, (err, res, body) =>
			response = [@parse(body)]
			done err, response if done
	
	create: (fields, done) ->
		for field of @fields
			fields[field] = @fields[field] if @fields.hasOwnProperty(field)
		
		request
			url: "#{ @url }/"
			method: 'POST'
			headers: @headers
			form: fields
			qs: @qs
		, (err, res, body) =>
			response = @parse body
			done err, response if done
	
	update: (fields, done) ->
		for field of @fields
			fields[field] = @fields[field] if @fields.hasOwnProperty(field)
		
		request
			url: "#{ @url }/#{ fields[@primaryKey] }"
			method: 'PUT'
			headers: @headers
			form: fields
			qs: @qs
		, (err, res, body) =>
			response = @parse body
			done err, response if done
	
	remove: (fields, done) ->
		request
			url: "#{ @url }/#{ fields[@primaryKey] }"
			method: 'DELETE'
			headers: @headers
			qs: @qs
		, (err, res, body) =>
			done err if done
	
	removeAll: (done) ->
		request
			url: "#{ @url }/"
			method: 'DELETE'
			headers: @headers
			qs: @qs
		, (err, res, body) =>
			done err if done
	
	@connect: (hosts, done) -> done()
	
	@disconnect: (done) -> done()
	
	@Extensions: {}
			
class REST.Extensions.ClassMethods
	init: ->
		return if @request

		@request = @::request=
			headers: {}
			qs: {}
			fields: {}
	
	url: (@url) ->
		@::url = @url

	header: (name, value) ->
		@init()

		@::request.headers[name] = @request.headers[name] = value

	headers: (headers) ->
		@init()

		for name of headers
			@header name, headers[name] if headers.hasOwnProperty name

	qs: (qs) ->
		@init()

		if arguments.length is 2 and qs instanceof String
			qs = qs: arguments[1]

		for key of qs
			@request.qs[key] = qs[key] if qs.hasOwnProperty key

	defaultField: (name, value) ->
		@init()

		@request.fields[name] = value

	defaultFields: (fields) ->
		@init()

		for name of fields
			@defaultField name, fields[name] if fields.hasOwnProperty name

module.exports = REST