--[[----------------------------------------------------------------------------

ADOBE CONFIDENTIAL
------------------
Copyright 2015 Adobe Systems Incorporated
All Rights Reserved.

NOTICE: All information contained herein is, and remain the property of
Adobe Systems Incorporated and its suppliers, if any. The intellectual and
technical concepts contained herein are proprietary to Adobe Systems
Incorporated and its suppliers and may be covered by U.S. and Foreign
Patents, patents in process, and are protected by trade secret or copyright
law.  Dissemination of this information or reproduction of this material is
strictly forbidden unless prior written permission is obtained from
Adobe Systems Incorporated.

----------------------------------------------------------------------------]]--

	-- WF.core.utils
local KSStringUtils = require 'KSStringUtils'

--------------------------------------------------------------------------------

local LrmAlbumQueryBuilder = {}
local WFPlatformInfo = require 'WFPlatformInfo'
--------------------------------------------------------------------------------

local kCollectionInfoFields = [[coreInfo.docId as assetId, captureDate, contentType, duration, importTimestamp, flag,
	croppedWidth, croppedHeight, fileName, width, height, apertureValue, isoSpeedRatings, 
	exposureTime, cameraMaker, cameraModel, rating, modifiedDate, isVideo, localUrl, fnumber, isMergedHDR,
	hasThumbnail, importedByUser, NULL AS purgeDate, hasEmbeddedDepthMap, developUserUpdated]]

if WFPlatformInfo.isAndroid then

	kCollectionInfoFields = [[coreInfo.docId as assetId, croppedWidth, croppedHeight, captureDate, fileName, modifiedDate, 
	thumbnailMD5, importTimestamp as importDate, hasThumbnail, importedByUser, isVideo, duration, needsUpdateAISettings]]


end

local fields = KSStringUtils.split( kCollectionInfoFields, "," )
LrmAlbumQueryBuilder.kCountCollectionInfoFields = #fields

--------------------------------------------------------------------------------

local function addRatingPredicate( ratingFilter, ratingComparisonOperator, predicate, queryParams )

	predicate = predicate .. " AND rating " .. ratingComparisonOperator .. " ?"
	table.insert( queryParams, ratingFilter )

	return predicate, queryParams

end

--------------------------------------------------------------------------------

local function isRatingPredicateRequired( ratingFilter, ratingComparisonOperator )

	if ratingComparisonOperator == ">=" and ratingFilter == 0 then
		return false
	elseif ratingComparisonOperator == "<=" and ratingFilter == 5 then
		return false
	end
	return true

end

--------------------------------------------------------------------------------


local function makeAlbumPredicate( albumId, assetFilter, assetTypeFilter, keyword, edited, ratingFilter, ratingComparisonOperator )
	
	local predicate = [[INNER JOIN album_asset
	                    ON coreInfo.docId == album_asset.assetId WHERE album_asset.albumId == ? ]]
	local queryParams = { albumId }
	
	
	if #assetFilter > 0 then
		
		predicate = predicate .. " AND ("
	
		for i = 1, #assetFilter do
		
			if i > 1 then
				predicate = predicate .. " OR "
			end
			
			local filter = assetFilter[ i ]
			
			if filter == 'pick' or filter == 'reject' or filter == 'unflagged' then
				predicate = predicate .. "flag == ?"
				table.insert( queryParams, filter )
			elseif filter == 'favorite' then
				predicate = predicate .. "favoriteCount > 0"
			elseif filter == 'comment' then
				predicate = predicate .. "commentCount > 0"
			end
			
		end
		
		predicate = predicate .. ")"
	end
	
	if #assetTypeFilter > 0 then
		
		predicate = predicate .. " AND ("
		
		for i = 1, #assetTypeFilter do
		
			if i > 1 then
				predicate = predicate .. " OR "
			end
			
			local assetType = assetTypeFilter[ i ]
			
			if assetType == 'image' then
				predicate = predicate .. "isVideo == ?"
				table.insert( queryParams, 0 )
			elseif assetType == 'video' then
				predicate = predicate .. "isVideo == ?"
				table.insert( queryParams, 1 )
			end
			
		end
		
		predicate = predicate .. ")"
	
	end

	if keyword ~= nil and #keyword > 0 then

		predicate = predicate .. " AND ("

		for i = 1, #keyword do

			if i > 1 then
				predicate = predicate .. " OR "
			end

			predicate = predicate .. "keyword == ? COLLATE NOCASE"
			table.insert( queryParams, keyword[ i ] )

		end

		predicate = predicate .. ")"

	end


	if edited ~= nil then
		predicate = predicate .. " AND "

		if edited == 1 then
			predicate = predicate .. "coreInfo.developUserUpdated IS NOT NULL"
		else
			predicate = predicate .. "coreInfo.developUserUpdated IS NULL"
		end
	end

	if isRatingPredicateRequired( ratingFilter, ratingComparisonOperator ) then
		predicate, queryParams = addRatingPredicate( ratingFilter, ratingComparisonOperator, predicate, queryParams )
	end
	
	return predicate, queryParams
	
end

--------------------------------------------------------------------------------


function LrmAlbumQueryBuilder.buildBestPhotosCoreInfoQuery(albumId, bestPhotosClusterId)

	local firstSortCriteria = 'sortOrder'
	local secondSortCriteria = 'captureDate'
	local firstSortOrder = 'DESC'
	local secondSortOrder = 'ASC'
	local parentId = ""
	if (bestPhotosClusterId and #bestPhotosClusterId > 0) then
		parentId = bestPhotosClusterId
	end
	local queryParams = { albumId, parentId }

	local sql = [[  SELECT distinct ]] .. kCollectionInfoFields .. [[, sortOrder, topicId
					FROM coreInfo
						INNER JOIN (
						SELECT topic_assets.assetId as assetId, topicId, sortOrder FROM
							( SELECT assetId FROM album_asset where albumId == ? ) AS source_album_assets
							INNER JOIN (
							SELECT assetId, album_asset.albumId as topicId, sortOrder FROM
								albums INNER JOIN album_asset
								ON (albums.docId == album_asset.albumId AND albums.subtype == 'topic'
										AND albums.parentId == ?
										)
								) AS topic_assets ON ( source_album_assets.assetId == topic_assets.assetId )
						)  AS album_topic_assets ON coreInfo.docId == album_topic_assets.assetId ]]

	sql = sql .. [[ ORDER BY ]] .. firstSortCriteria .. [[ ]] .. firstSortOrder .. [[, ]] .. secondSortCriteria .. [[ ]] .. secondSortOrder
	return sql, queryParams

end
--------------------------------------------------------------------------------

function LrmAlbumQueryBuilder.buildCoreInfoQuery( albumId, ascending, assetFilter, assetTypeFilter, keyword, edited, sortCriteria, ratingFilter, ratingComparisonOperator, isSearch )

	local order = 'DESC'
    
    if ascending or isSearch then
        order = 'ASC'
    end

	local predicate = ""
	local queryParams = {}

	if albumId then
        predicate, queryParams = makeAlbumPredicate( albumId, assetFilter, assetTypeFilter, keyword, edited, ratingFilter, ratingComparisonOperator )
	end
	
	-- INFO [pkamin 2013-12-11]: we map the filename criteria to the table column with lowercase names and apply the correct collation
	if sortCriteria == 'fileName' then
		sortCriteria = 'fileName COLLATE i18n_collate '
	end
	
	local secondOrder = 'coreInfo.captureDate'
	
	if isSearch then
		sortCriteria = 'TEMP_search.sortOrder'
	elseif sortCriteria == 'userDefined' then
		sortCriteria = 'sortOrder'
	elseif sortCriteria == 'captureDate' then
		secondOrder = 'coreInfo.docId'
	elseif sortCriteria == 'importDate' then
		sortCriteria = "importTimestamp"
	elseif sortCriteria == 'mostFavorited' then
		sortCriteria = "favoriteCount "						
	elseif sortCriteria == 'quality' then -- for Best Photos
		sortCriteria = 'captureDate'
		secondOrder = 'coreInfo.docId'
	end
	
	local selectSubqueries = [[, (SELECT COUNT(comment.docId) FROM comment WHERE comment.assetId == coreInfo.docId AND 
								spaceId IN (SELECT spaceId FROM space_album WHERE albumId == ? )) AS commentCount, 
							(SELECT COUNT(spacefavorite.docId) FROM spacefavorite WHERE spacefavorite.assetId == coreInfo.docId AND 
								spaceId IN (SELECT spaceId FROM space_album WHERE albumId == ? )) AS favoriteCount ]]
								
	if WFPlatformInfo.isAndroid then
		-- Android does not need fav/comment as there is not support for it now
		selectSubqueries = [[ , 0 AS commentCount, 0 AS favoriteCount ]]
	end
	
	local sql = [[SELECT ]] .. kCollectionInfoFields .. selectSubqueries
	
	if isSearch then
		sql = sql .. ", TEMP_search.sortOrder"
	end

	sql = sql .. [[ FROM coreInfo ]]
	
	if isSearch then
		sql = sql .. [[ INNER JOIN TEMP_search ON coreInfo.docId = TEMP_search.docId ]]
	end

	if keyword ~= nil and #keyword > 0 then
		sql = sql .. [[ INNER JOIN keywords ON coreInfo.docId = keywords.docId ]]
	end

	sql = sql .. predicate ..
			[[ ORDER BY ]] .. sortCriteria .. [[ ]] .. order .. [[, ]] .. secondOrder .. [[ ]] .. order
	
	if sortCriteria == 'modifiedDate' then
		sql = sql .. [[, fileName COLLATE i18n_collate ]] .. order .. [[, coreInfo.docId ]] .. order
	end

	if not WFPlatformInfo.isAndroid then
		table.insert( queryParams, 1, albumId )
		table.insert( queryParams, 1, albumId )
	end
	
	return sql, queryParams
	
end

--------------------------------------------------------------------------------

return LrmAlbumQueryBuilder
