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

WFCatSearchByCamera.lua

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

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

NOTICE: All information contained herein is, and remains 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 are protected by all applicable
intellectual property laws, including trade secret and copyright laws.
Dissemination of this information or reproduction of this material is
strictly forbidden unless prior written permission is obtained from
Adobe Systems Incorporated.

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

local KSTableUtils = require 'KSTableUtils'
local KSStringUtils = require 'KSStringUtils'
local WFCatCameraCanonicalMap = require 'WFCatCameraCanonicalMap'

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

local derefOpt = KSTableUtils.derefOpt

local isValidSearchableAssetDocument = assert( require 'WFCatIndexUtils'.isValidSearchableAssetDocument )


--==============================================================================

local WFCatSearchByCamera = {}

--[[
	Index definitions for finding assets by camera.  The SQLite index only;
--]]

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

local _canonical_make_map = WFCatCameraCanonicalMap["MakeMap"]
local _canonical_model_map = WFCatCameraCanonicalMap["ModelMap"]

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

local function isNonEmptyString( str )

	return type( str ) == "string" and #str > 0

end

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

local function getFirstWord( str )

	local words = KSStringUtils.split( str, ' ' )

	return type( words ) == "table" and words[ 1 ] or str

end

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

local function makeLowercaseAndTrim( str )

	local strLC = ''
					
	if str then

		strLC = KSStringUtils.lower( str )
		strLC = KSStringUtils.trim( strLC )
		
	end

	return strLC

end

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

function WFCatSearchByCamera.generateIndexSchema( indexStoreSchema )

	indexStoreSchema:addTable {

		sql = [[CREATE TABLE cameras( camera TEXT, cameraLC, isCatalogDocument )]],

		useLocalId = true,
		
		hasOneRowPerDocument = true,
		
		relevantTypeSubtypeTuples = {
			{ 'asset', '*' },
		},

		map = function( docValue, emit )

			local isSearchable, searchableDoc = isValidSearchableAssetDocument( docValue )

			if not isSearchable or not searchableDoc then

				return

			end
			
			local isCatalogDocument = derefOpt( searchableDoc, "_spaceId" ) and 0 or 1
			
			local makeAndModelStr = derefOpt( searchableDoc, 'importSource', 'camera', 'name' )
			
			if not makeAndModelStr then

				local maybeModelStr = derefOpt( searchableDoc, 'xmp', 'tiff', 'Model' ) 

				local maybeMakeStr = derefOpt( searchableDoc, 'xmp', 'tiff', 'Make' ) 
			
				-- map the make/model to canonical names to match the Oz camera-name logic
				-- https://git.corp.adobe.com/oz/federated-index-worker/blob/master/lib/metadata.rb#L524
				if maybeModelStr and _canonical_model_map[ maybeModelStr ] then
					maybeModelStr = _canonical_model_map[ maybeModelStr ]
				end
				
				if maybeMakeStr and _canonical_make_map[ maybeMakeStr ] then
					maybeMakeStr = _canonical_make_map[ maybeMakeStr ]
				end
				
				local isModelStrNonEmpty = isNonEmptyString( maybeModelStr )
				local isMakeStrNonEmpty = isNonEmptyString( maybeMakeStr )
				
				if not isModelStrNonEmpty and 
						not isMakeStrNonEmpty then

	-- [anmurark 2018-08]: NMB-9127: Removing this for 1.5 to match the USS based cameras list
	--				local noCamera = WFCatSearchAndSortConstants.General.NO_CAMERA_INFO
	--
	--				emit( noCamera, makeLowercaseAndTrim( noCamera ), isCatalogDocument )

					return

				end

				if isModelStrNonEmpty and 
						not isMakeStrNonEmpty then

					-- no make string, use model

					emit( maybeModelStr, makeLowercaseAndTrim( maybeModelStr ), isCatalogDocument )

					return

				end

				if not isModelStrNonEmpty and 
						isMakeStrNonEmpty then

					-- no model string, use make

					emit( maybeMakeStr, makeLowercaseAndTrim( maybeMakeStr ), isCatalogDocument )

					return

				end

				-- we have a non empty model and non empty make string

				-- check if the model contains the make str, if so, just report the model str

				if string.lower( getFirstWord( maybeModelStr ) ) == 
						string.lower( getFirstWord( maybeMakeStr ) ) then

					emit( maybeModelStr, makeLowercaseAndTrim( maybeModelStr ), isCatalogDocument )

					return

				end

				-- otherwise combine make and model into one string
				
				makeAndModelStr = string.format( "%s %s" , maybeMakeStr, maybeModelStr )
			
			end
			
			emit( makeAndModelStr, makeLowercaseAndTrim( makeAndModelStr ), isCatalogDocument )

		end,

	}

	indexStoreSchema:addIndex
		[[CREATE INDEX cameras_camera ON cameras( camera, docId )]]
	indexStoreSchema:addIndex 
		[[CREATE INDEX cameras_cameraLC ON cameras( cameraLC COLLATE i18n_collate )]]
	indexStoreSchema:addIndex 
		[[CREATE INDEX cameras_isCatalogDocument ON cameras( isCatalogDocument )]]
	
end

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

function WFCatSearchByCamera.addSearchToSearchSchema( searchSchema )

	searchSchema:addSearchableData {
		term = 'cameras',
		dataType = 'camerasTerm',
		sql = [[SELECT docId FROM cameras WHERE camera = ? ORDER BY docId]],
		query_params = {
			'camera',
		},
	}

end

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

function WFCatSearchByCamera.collectCameraDetailsOfRequiredAssets( wfCatalog, assetLocalIds )
	
	return wfCatalog:indexStore():query {
		sql = [[SELECT DISTINCT camera
						FROM cameras
						INNER JOIN CARRAY( ?, ?, 'int32' ) AS assetLocalIds ON assetLocalIds.value == cameras.docId
						ORDER BY cameraLC COLLATE i18n_collate ASC]],
		calm = 5,
		assetLocalIds,
		#assetLocalIds,
	}
	
end

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

function WFCatSearchByCamera.collectCameraDetailsOfAllAssets( wfCatalog )
	
	return wfCatalog:indexStore():query {
		sql = [[SELECT DISTINCT camera
						FROM cameras
						WHERE isCatalogDocument = 1
						ORDER BY cameraLC COLLATE i18n_collate ASC]],
		calm = 5,
	}
	
end

--==============================================================================

return WFCatSearchByCamera
