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

WFCatErrorHandler.lua

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

ADOBE CONFIDENTIAL
------------------
Copyright 2016 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.

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

	--Rx
local Rx = require 'Rx'
local Observable = Rx.Observable

local KSTableUtils = require 'KSTableUtils'
local WFArguments = require 'WFArguments'

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

local derefOpt = KSTableUtils.derefOpt
local check = assert( WFArguments.check )

local updaterTask

local WFCatInvalidOriginalHandler = {}

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

local function invalid_originals_table( )

	return {

		sql = [[CREATE TABLE invalid_originals( assetId )]],
		
		relevantTypeSubtypeTuples = {
			{ 'asset', '*' },
		},
		
		map = function( docValue, emit )
			
			if docValue.type == 'asset' and docValue._deleted ~= true then
				
				local haslocalOriginalError = derefOpt( docValue, '_localOnly', 'localOriginalError' )
				
				if haslocalOriginalError then
					emit( docValue._id )
				end
			end
		end,

		hasOneRowPerDocument = true,
	}
	
end


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

local function performInvalidOriginalFix( wfCatalog )

	return wfCatalog:indexStore():queryOnce {
		sql = [[SELECT docId FROM invalid_originals LIMIT 5]],
		quiesceUntilUpToDate = true,
		singleColumnQuery = true
	}
	:flatMap( function( docIds )
	
		if not next( docIds ) then
			return Observable.just( false )
		end
		
		return wfCatalog:docStore():bulkDocValue( docIds )
				:flatMap( function( docValueArray )
				
					return Observable.from( docValueArray )		
						:map( function( docValue )
							-- get original location
							local filePath = require 'WFCatFileSpec'.buildOriginalPathFromDocValue( docValue )
							
							local fileSize = require 'WFFileUtils'.fileAttributes( filePath ).fileSize
							
							return require 'WFCrypto'.asyncDigestFile( filePath, 'SHA256' )
								:map( function( sha256 )
									
									return {
										_id = docValue._id,
										_localOnly = {
											localOriginalError = { _delete = true },
											files = {
												original = {
													master = {
														sha256 = sha256,
														size = fileSize,
													}
												}
											}
										},
										importSource = {
											sha256 = sha256,
											fileSize = fileSize,
										}
									}
									
								end )
							
						end )
						:flatMerge( 1 )
						:toArray()
					
				end )
				:flatMap( function( allOverlays )
					if #allOverlays > 0 then
						return wfCatalog:docStore():bulkApplyOverlay( allOverlays )
							:map( function() return true  end )
					else
						return Observable.just( false )
					end				
				end )
	end )
	:map( function( didWork )
			
		-- if we didn't do any work, stop the continuous task.
		-- it will be restarted on next launch
		if not didWork then
			updaterTask:stopContinuousTask()
			updaterTask = nil
		end
		
	end )
end

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

function WFCatInvalidOriginalHandler.fixInvalidOriginals( wfCatalog )
	
	local updateTask = function() return performInvalidOriginalFix( wfCatalog ) end
	
	if not updaterTask then
		
		updaterTask = require 'WFRxContinuousTask'( "WFCatInvalidOriginalHandler", updateTask )
	
		updaterTask:startContinuousTask()
	end	
end

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

function WFCatInvalidOriginalHandler.generateIndexSchema( indexStoreSchema )

	check( 'WFRxIndexStoreSchema' )

	indexStoreSchema:addTable( invalid_originals_table( ) )

end


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

return WFCatInvalidOriginalHandler
