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

WFCatSearchByCaptureDate.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 WFCatSearchQuery = require 'WFCatSearchQuery'


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

local derefOpt = KSTableUtils.derefOpt

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


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

local WFCatSearchByCaptureDate = {}

--[[
	Index definitions for finding assets by date.  The SQLite index only;
		the table definition is shared (``asset`` table).
	Index definitions for identifying what years, months and days have assets.
	Queries for the above finding assets by date.
--]]

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

function WFCatSearchByCaptureDate.generateIndexSchema( indexStoreSchema )

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

	indexStoreSchema:addTable {

		sql = [[CREATE TABLE captureDate( subType, year, month, dayOfMonth, completeMonth, completeDate, completeTime )]],
		
		relevantTypeSubtypeTuples = {
			{ 'asset', '*' },
		},

		map = function( docValue, emit )

			local isSearchable, searchableDoc = isValidSearchableAssetDocument( docValue )
			
			local hasSpaceId = not not docValue._spaceId
			
			if isSearchable and searchableDoc and not hasSpaceId then
			
				local subType = docValue.subtype
				local captureDate = derefOpt( searchableDoc, 'captureDate' )
				
				-- assets without a true captureDate will have a captureDate of '0000-00-00T00:00:00' 
				-- and so these year/month/day values may be 0. ignore these dates for now
				--if captureDate and not string.find( captureDate, "^0000" ) then
				if captureDate then

					local _, _, year, month, dayOfMonth = string.find( captureDate, 
						"^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])" )
					
					local startPos, _, hour, minute, seconds = string.find( captureDate, "T([0-9][0-9]):([0-9][0-9]):([0-9][0-9])" )
					if not startPos then
						-- try without seconds, it'll still be a rougly usable time
						_, _, hour, minute = string.find( captureDate, "T([0-9][0-9]):([0-9][0-9])" )
					end
					
					if year and month and dayOfMonth then
					
						year, month, dayOfMonth, hour, minute, seconds = tonumber( year ), tonumber( month) , tonumber( dayOfMonth ), 
																		tonumber( hour ) or 0, tonumber( minute ) or 0, tonumber( seconds ) or 0
						
						if year and month and dayOfMonth then
							local combinedTime = seconds + minute * 100 + hour * 10000 + dayOfMonth * 1000000 + month * 100000000 + year * 10000000000
							local combinedDate = dayOfMonth + month * 100 + year * 10000
							local combinedMonth = month + year * 100
							emit( subType, year, month, dayOfMonth, combinedMonth, combinedDate, combinedTime )
							
						end
						
					end
					
				end

			end

		end,

		useLocalId = true,
		hasOneRowPerDocument = true,
	}
	
	indexStoreSchema:addIndex
		[[CREATE INDEX captureDate_completeMonth ON captureDate( completeMonth, docId )]]

	indexStoreSchema:addIndex
		[[CREATE INDEX captureDate_completeDate ON captureDate( completeDate, docId )]]
	
	indexStoreSchema:addIndex 
		[[CREATE INDEX captureDate_completeDate_subType ON captureDate( completeDate, subType )]]

end


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

function WFCatSearchByCaptureDate.captureDates( wfCatalog )

	return wfCatalog:indexStore():query( {

			sql = 
				[[SELECT completeDate, count(completeDate) as CountOf 
				  FROM captureDate 
				  WHERE subtype IN ( 'image', 'video' ) 
				  GROUP BY completeDate
				  ORDER BY completeDate DESC ]],
				  
			calm = WFCatSearchQuery.defaultQueryCalmRate 
		
		} )

end

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

function WFCatSearchByCaptureDate.addSearchToSearchSchema( searchSchema )

	searchSchema:addSearchableData {
		term = 'captureInfoRange',
		dataType = 'dateRangeTerm',
		sql = [[SELECT docId, year FROM captureDate WHERE %COLUMN_NAME >= ? and %COLUMN_NAME <= ? ORDER BY docId]],
		query_params = {
			'minValue',
			'maxValue'
		},
		allowedColumnNames = {
			year = true ,
			month = true, 
			dayOfMonth = true, 
			completeMonth = true, 
			completeDate =  true
		},	
	}	
	
	searchSchema:addSearchableData {
		term = 'dateMultipleInfoSearch',
		dataType = 'dateInfoDynamicTerm',
		tableName = 'captureDate',
		query_params = {
			'columnInfo',
		},
		allowedColumnNames = {
			year = true ,
			month = true, 
			dayOfMonth = true, 
		},	
	}	
	
	searchSchema:addSearchableData {
		term = 'captureCompleteDate',
		dataType = 'uint',
		query_params = {
			'completeDate',
		},
		sql_table = 'captureDate',
		column = 'completeDate',
	}
	
	searchSchema:addSearchableData {
		term = 'captureMonthAndYear',
		dataType = 'uint',
		query_params = {
			'completeMonth',
		},
		sql_table = 'captureDate',
		column = 'completeMonth',
	}
	
	searchSchema:addSearchableData {
		term = 'captureYear',
		dataType = 'uint',
		query_params = {
			'year',
		},
		sql_table = 'captureDate',
		column = 'year',
	}
	
	searchSchema:addSearchableData {
		term = 'month',
		dataType = 'uint',
		query_params = {
			'month',
		},
		sql_table = 'captureDate',
		column = 'month',
	}
	
	searchSchema:addSearchableData {
		term = 'dayOfMonth',
		dataType = 'uint',
		query_params = {
			'dayOfMonth',
		},
		sql_table = 'captureDate',
		column = 'dayOfMonth',
	}
	
	searchSchema:addSearchableData {
		term = 'captureDate',
		dataType = 'alpha',
		sql_table = 'assets',
		column = 'captureDate',
	}

end

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

return WFCatSearchByCaptureDate
