local table = require "table"
local oo = require "loop.simple"
local Entity = require "LuaOrm.Entity"
local Association = require "LuaOrm.Associations.AssociationBase"
local string = require "string"

local error = error
local type = type
local ipairs = ipairs
local pairs = pairs
local print = print

module("LuaOrm.Associations.BelongsToOneAssociation")
oo.class(_M, Association)


function Validate(self, model, associatedModel)
	if (not model) then
		return nil
	end
	self.m_model = model
	if (not associatedModel) then
		return nil
	end
	self.m_associatedModel = associatedModel
	if (not self.m_foreignKeys) then
		self.m_foreignKeys = self.ResolveForeignKeys(self.m_model, self.m_associatedModel, "To")
		if (self.m_foreignKeys == nil) then
			error(string.format("Cannot define relationship without foreign keys (%s => %s)", model.tableName, associatedModel.tableName))
		end
	end
	return self
end

function GetJoinExpression(self)
	local expression = {}
	local ds = self.m_associatedModel.dataSource
	for remoteName, localName in pairs(self.m_foreignKeys) do
		table.insert(expression, ds.Format("%Q.%Q = %Q.%Q",
			self.m_model.tableName, localName, self.m_associatedModel.tableName, remoteName
		))
	end
	return table.concat(expression, " AND ")
end

function BuildQuery(self, parent)
	local ds = self.m_associatedModel.dataSource
	local useNolock = ds.m_dbmsPlatform.supportsNolock and "(nolock)" or ""
	
	local query = ds.Format("SELECT DISTINCT %s FROM %Q %s WHERE", 
						ds:GetProjectedFields(self.m_associatedModel),
						self.m_associatedModel.tableName, useNolock)	
	local condition = {}
	for remoteName, localName in pairs(self.m_foreignKeys) do
		if (parent[localName]) then
			table.insert(condition, ds.Format("%Q.%Q = %s", self.m_associatedModel.tableName, remoteName, ds:Escape(self.m_model, localName, parent[localName])))
		end
	end
	return query .. table.concat(condition, " AND ")
end

