--[=[
	Loads data. This returns the originally loaded data.
	@param keyName string
	@param defaultValue any?
	@return any?
]=]

function DataStore:Load(keyName, defaultValue)
	return self:_promiseLoad()
		:Then(function(data)
			return self:_afterLoadGetAndApplyStagedData(keyName, data, defaultValue)
		end)
end

function DataStore:_saveData(writer)
	local maid = Maid.new()

	local promise = Promise.new()
	promise:Resolve(maid:GivePromise(DataStorePromises.updateAsync(self._robloxDataStore, self._key, function(data)
		if promise:IsRejected() then
			-- Cancel if we have another request
			return nil
		end

		data = writer:WriteMerge(data or {})
		assert(data ~= DataStoreDeleteToken, "Cannot delete from UpdateAsync")

		if DEBUG_WRITING then
			print("[DataStore] - Writing", game:GetService("HttpService"):JSONEncode(data))
		end

		return data
	end, function(err)
		-- Might be caused by Maid rejecting state
		warn("[DataStore] - Failed to UpdateAsync data", err)
		return Promise.rejected(err)
	end)))

	self._maid._saveMaid = maid

	if self.Saving.Destroy then
		self.Saving:Fire(promise)
	end

	return promise
end

function DataStore:_promiseLoad()
	if self._loadPromise then
		return self._loadPromise
	end

	self._loadPromise = self._maid:GivePromise(DataStorePromises.getAsync(self._robloxDataStore, self._key)
		:Then(function(data)
			if data == nil then
				return {}
			elseif type(data) == "table" then
				return data
			else
				return Promise.rejected("Failed to load data. Wrong type '" .. type(data) .. "'")
			end
		end, function(err)
			-- Log:
			warn("[DataStore] - Failed to GetAsync data", err)
			return Promise.rejected(err)
		end))

	return self._loadPromise
end

return DataStore
