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

LrmCatPreset.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.

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

-- WF.core.reactive
local Rx = require 'Rx'

-- WF.core.rxlua
local WFRxPromiseBridge = require 'WFRxPromiseBridge'

local WFArguments = require "WFArguments"
local KSTableUtils = require "KSTableUtils"
local KSData = require "KSData"
local KSPathUtils = require "KSPathUtils"
local WFFileUtils = require "WFFileUtils"

local check = WFArguments.check

local asKSPromise = WFRxPromiseBridge

local derefOpt = KSTableUtils.derefOpt

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

local LrmCatPreset = {}

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

local function getExternalPreset( catalog, docValue, sha256, catalogId )

    local hrefXmpDevelop = derefOpt(docValue, '_serverProvidedMetadata', 'links', '/rels/master', 'href' )
    local isInvalidXmpDevelop = derefOpt(docValue, '_serverProvidedMetadata', 'links', '/rels/master', 'invalid' )
    local xmpFiles = derefOpt( docValue, '_localOnly', 'files', 'presetProfile' )

    local documents = KSPathUtils.getStandardFilePath( 'carouselDocuments' )

    sha256 = sha256 or derefOpt( docValue, 'importSource', 'sha256' )

    if xmpFiles and xmpFiles.path then

        local xmpAbsPath = KSPathUtils.child( KSPathUtils.child( documents, catalogId ), xmpFiles.path )
        if xmpFiles.sha256 == sha256 and WFFileUtils.exists( xmpAbsPath ) then

            -- preset is already present
            return Rx.Observable.just( KSData.memoryMappedContentsOfFile( xmpAbsPath ), xmpFiles.path )
        else if isInvalidXmpDevelop then
                return Rx.Observable.just( KSData.memoryMappedContentsOfFile( xmpAbsPath ), xmpFiles.path )
            end
        end

        -- remove the stale file
        WFFileUtils.deleteFile( xmpAbsPath )

    end

    if not sha256 or not hrefXmpDevelop then

        return Rx.Observable.throw( 'No Preset/Profile available' )

    end

    return catalog:getCatUser()
    :flatMap( function( ozUser )

        return Rx.Observable.combineLatest( function( xmpCameraRaw, wfCatalog )

            local presetPath

            if docValue and docValue.name then
                local catalogId = wfCatalog:ozCatalogSpec():catalogId()

                local fileName = docValue.id or docValue._id
                presetPath = 'Profiles/Settings/UserStyles/' .. fileName .. '.xmp'

                local success, result = pcall( KSData.saveToUniquelyNamedFile, xmpCameraRaw, KSPathUtils.child( KSPathUtils.child(documents, catalogId), presetPath) )

                if not success then
                    return 'error', false
                end

            end

            return tostring(xmpCameraRaw), presetPath

        end,
            ozUser:getBinary( hrefXmpDevelop ),
            catalog._wfCatalogStream ) -- TODO [ind31010 2016-09-28]: this is totally hacky, but how to do this?
    end)

    :flatMap( function(xmpCameraRawOrError, relativePresetPath)

        local returnValue = Rx.Observable.just (xmpCameraRawOrError, relativePresetPath)
        if xmpCameraRawOrError ~= 'error' then

            local docId = docValue._id or docValue._docId
            -- update the document
            returnValue = catalog:docStore():applyOverlay {
                _id = docId,
                _localOnly = {
                    files = {
                        presetProfile = {
                            sha256 = sha256,
                            path = relativePresetPath, -- According to this bug LRMA-4199470, there are chances that the presetPath can be full path in few devices (before the fix) and relative path in few devices (after the fix)
                            uploadStatus = { _delete = true },
                        }
                    }
                }
            }

        end

        return returnValue
        :map( function ()
            return xmpCameraRawOrError
        end )

    end )

end

--[[!
	\brief retrieve and store the external xmpCameraRaw develop settings

	\param catalog the catalog service
	\param docIdOrValue the document id or the docValue
	\param sha256 the sha256 of the external develop settings (optional)
	\return (KSData, string) xmpCameraRaw and the relative path to the file
--]]
function LrmCatPreset.getExternalPreset( catalog, docIdOrValue, sha256, catalogId )

    check( 'OzCatalogService', 'table|string', '?string')

    if type(docIdOrValue) == 'table' then
        return getExternalPreset( catalog, docIdOrValue, sha256, catalogId )
    end

    return catalog:docStore():docValue( docIdOrValue )

    :flatMap( function( docValue )

        return getExternalPreset( catalog, docValue, sha256, catalogId )

    end )

end

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

function LrmCatPreset.getExternalPresetP( catalog, docIdOrValue, sha256 )

    return catalog:getCatalogIdP()
    :mapDataP_new( function ( catalogId )

        return LrmCatPreset.getExternalPreset( catalog, docIdOrValue, sha256, catalogId )
        :call( asKSPromise )

    end)

end


return LrmCatPreset