local LrPathUtils = import("LrPathUtils")
local LrTasks = import("LrTasks")
local LrFileUtils = import("LrFileUtils")
local LrView = import("LrView")
local LrStringUtils = import("LrStringUtils")
local LrDate = import("LrDate")
local LrDialogs = import("LrDialogs")
local LrApplication = import("LrApplication")

local ExportProcessRenderedPhotos = {}

ExportProcessRenderedPhotos.exportPresetFields = {
    { key = 'exportImageFormat', default = 'ORIGINAL' },
}

ExportProcessRenderedPhotos.hideSections = {'exportLocation', 'fileNaming', 'imageSettings', 'outputSharpening', 'metadata', 'watermarking', 'video'}

ExportProcessRenderedPhotos.canExportToTemporaryLocation = true

ExportProcessRenderedPhotos.allowFileFormats = {'ORIGINAL', 'TIFF'}

local random = math.random
local function uuid()
    local template ='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
    return string.gsub(template, '[xy]', function (c)
        local v = (c == 'x') and random(0, 0xf) or random(8, 0xb)
        return string.format('%x', v)
    end)
end

function ExportProcessRenderedPhotos.processRenderedPhotos( functionContext, exportContext )

	local exportSession = exportContext.exportSession

	-- Make a local reference to the export parameters.
	
	local exportParams = exportContext.propertyTable
	
	-- Set progress title.

	local nPhotos = exportSession:countRenditions()

	local progressScope = exportContext:configureProgress{
						title = nPhotos > 1
									and LOC( "$$$/MPExtrasPluginAppName/Upload/Progress=Uploading ^1 photos to MPExtrasAppName", nPhotos )
									or LOC ("$$$/MPExtrasPluginAppName/Upload/Progress/One=Uploading one photo to MPExtrasAppName"),
					}

	-- Save off uploaded photo IDs so we can take user to those photos later.
	
	local uploadedPhotoIds = {}
	
	local command = nil
	local collection = nil
	local firstPhotoPath = nil
	local numberOfRenderedPhotos = 0	
	local collections = nil
	local keywords = nil

	-- metadata
	local copyName = nil
	local title = nil
	local caption = nil
	local copyright = nil
	local copyrightStatus = nil
	local creator = nil
	local location = nil
	local rating = nil
	local label = nil
    local tempFiles = {}

	for i, rendition in exportContext:renditions{ stopIfCanceled = true } do
	
		-- Get next photo.

		local success, pathOrMessage = rendition:waitForRender()
		
		-- Check for cancellation again after photo has been rendered.
		
		if progressScope:isCanceled() then 
			command = nil
			break 
		end

		if success then
			local photo = rendition.photo
			if collections == nil then
				collections = photo:getContainedCollections()
			else 
				collections = intersectArrays(collections, photo:getContainedCollections())
			end
			
			if keywords == nil then
				keywords = photo:getRawMetadata("keywords")
			else
				keywords = intersectArrays(keywords, photo:getRawMetadata("keywords"))
			end

			-- storing metadata

			if copyName == nil then
				copyName = photo:getFormattedMetadata("copyName")
			end

			if title == nil then
				title = photo:getFormattedMetadata("title")
			end

			if caption == nil then
				caption = photo:getFormattedMetadata("caption")
			end

			if copyright == nil then
				copyright = photo:getFormattedMetadata("copyright")
			end

			if copyrightStatus == nil then
				copyrightStatus = photo:getRawMetadata("copyrightState")
			end

			if creator == nil then
				creator = photo:getFormattedMetadata("creator")
			end

			if location == nil then
				location = photo:getFormattedMetadata("location")
			end

			if rating == nil then
				rating = photo:getRawMetadata("rating")
			end

			if label == nil then
				label = photo:getFormattedMetadata("label")
			end

			-- storing metadata end


			numberOfRenderedPhotos = numberOfRenderedPhotos + 1
			if command == nil then
				command = "MPLightroomBridgePath"
			end
			
			if firstPhotoPath == nil then
				firstPhotoPath = pathOrMessage
				command = command .. " \"" .. firstPhotoPath .. "\""
			end
			if  i >= 2 then
				if collection == nil then
					collection = string.len(firstPhotoPath) .. ":" .. firstPhotoPath
				end
				collection = collection .. string.len(pathOrMessage) .. ":" .. pathOrMessage
			end

            tempFiles[photo.path] = pathOrMessage
		end
	end
	
	if command ~= nil then
	
		if collection ~= nil then
			command = command .. " -MPPhotoCollection " .. LrStringUtils.encodeBase64(collection)
		end

        local resPath = nil
        local catalog = nil
        local photosForExport = {}
        for photo in exportSession:photosToExport() do
            local photoPath = photo.path
            catalog = photo.catalog
            local pathName = LrPathUtils.removeExtension(photoPath)
            pathName = pathName .. "_" .. "MPExtrasPluginAppName" .. "_Processed"
            resPath = LrPathUtils.addExtension(pathName, "tiff")
            local pathIndex = 0
            while LrFileUtils.exists(resPath) do
                local indexedPathName = pathName .. "_" ..  pathIndex
                resPath = LrPathUtils.addExtension(indexedPathName, "tiff")
                pathIndex = pathIndex + 1
            end

            photosForExport[tempFiles[photoPath]] = resPath
        end

        if resPath ~= nil then
            command = command .. " -MPResPath " .. LrStringUtils.encodeBase64(resPath)
        end

        local savedPaths = nil
        for key, path in pairs(photosForExport) do
            local temStr = key .. "#@#" .. path
            if savedPaths == nil then
                savedPaths = string.len(temStr) .. ":" .. temStr
            else
                savedPaths = savedPaths .. string.len(temStr) .. ":" .. temStr
            end
        end

        if savedPaths ~= nil then
            command = command .. " -MPPathsForSave " .. LrStringUtils.encodeBase64(savedPaths)
        end

        command = command .. " -MPWait" .. " -MPAppBundlePath \"" .. "MPAppBundlePathTemplateKeyword\""
		
		LrTasks.execute(command)
		
		if catalog ~= nil and resPath ~= nil and LrFileUtils.exists(resPath) then
			local addedPhoto = nil
			catalog:withWriteAccessDo("0",
				function(context)
                    for key, path in pairs(photosForExport) do
                        addedPhoto = catalog:addPhoto(path, nil, nil)

                        if addedPhoto ~= nil then
                            if collections ~= nil then
                                for k, v in pairs(collections) do
                                    v:addPhotos({addedPhoto})
                                end
                            end
                            
                            local currentKeywords = addedPhoto:getRawMetadata("keywords")
                            if (numberOfElementsInArray(currentKeywords) == 0) and (numberOfElementsInArray(keywords) > 0) then
                                for k, v in pairs(keywords) do
                                    addedPhoto:addKeyword(v)
                                end
                            end

                            -- restoring metadata
                            addedPhoto:setRawMetadata("copyName", copyName)
                            addedPhoto:setRawMetadata("title", title)
                            addedPhoto:setRawMetadata("caption", caption)
                            addedPhoto:setRawMetadata("copyright", copyright)
                            addedPhoto:setRawMetadata("copyrightState", copyrightStatus)
                            addedPhoto:setRawMetadata("creator", creator)
                            addedPhoto:setRawMetadata("location", location)
                            addedPhoto:setRawMetadata("rating", rating)
                            addedPhoto:setRawMetadata("label", label)
                        end
                    end
				end
			)

			if addedPhoto ~= nil then
				catalog:setSelectedPhotos(addedPhoto, {addedPhoto})
			end
		end
	end
end

function ExportProcessRenderedPhotos.startDialog( propertyTable )
	local startTime = LrDate.currentTime()
	while not g_MPExtrasPluginAppName_presetsLoaded do
		local currentTime = LrDate.currentTime()
		if currentTime - startTime > 5 then 
			break 
		end
	end
end

function ExportProcessRenderedPhotos.updateExportSettings( exportSettings )
    exportSettings.exportImageFormat = exportSettings.LR_format
    exportSettings.LR_removeLocationMetadata = false
end

function intersectArrays(array1, array2)
	local result = {}
	local count = 0
	if array1 ~= nil and array2 ~= nil then
		for k1, v1 in pairs(array1) do
			for k2, v2 in pairs(array2) do
				if v1 == v2 then
					result[count] = v1
					count = count + 1
					break
				end
			end
		end
	end
	return result
end

function numberOfElementsInArray(array)
	local result = 0
	if array ~= nil then
		for k, v in pairs(array) do
			result = result + 1
		end
	end
	return result
end

return ExportProcessRenderedPhotos
