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

WFCatEditDefaultsTest.lua

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

ADOBE CONFIDENTIAL
------------------
Copyright 2020 Adobe
All Rights Reserved.

NOTICE: All information contained herein is, and remains
the property of Adobe and its suppliers, if any. The intellectual
and technical concepts contained herein are proprietary to Adobe
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.

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

	-- WF.core.self_test
local WFRxTestCase = require 'WFRxTestCase'

	-- WF.core.utils
-- local KSIdGenerator = require 'KSIdGenerator'
-- local KSTableUtils = require 'KSTableUtils'
local WFPlatformInfo = require 'WFPlatformInfo'
local WFModelsUtils = require 'WFModelsUtils'

	-- WF.managed_catalog
local WFCatMockCatalog = require 'WFCatMockCatalog'

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

local WFCatMockCatalog_createFakeWFCatalog = assert( WFCatMockCatalog.createFakeWFCatalog )

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

local function createFakeWFCatalog( rxTest, expectedRequestResponse )

	local optArgs = {}

	if WFPlatformInfo.isMobile() then
		optArgs.indexDefinitions = 'LrmCatalogIndexDefinitions.lua'
	end

	return WFCatMockCatalog_createFakeWFCatalog( rxTest, nil, expectedRequestResponse, optArgs )

end

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

local function mapAwayCruft( docValue )

	docValue._changeCounter = nil
	docValue._localId = nil
	docValue._revId = nil
	docValue.userCreated = nil
	docValue.userUpdated = nil

	return docValue

end

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

return function( optSubmodelsByImplementation, maybeExistingTestClass )

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

	local function callFunctionOrSubmodel( rxTest, wfCatalog, fnNamespace, fnName, ... )
	
		return WFModelsUtils.callFunctionOrSubmodel( rxTest, optSubmodelsByImplementation, wfCatalog, fnNamespace, fnName, ... )
					
	end

	----------------------------------------------------------------------------
	
	local WFCatEditDefaultsTest =  maybeExistingTestClass or {}
	
	----------------------------------------------------------------------------
		
	function WFCatEditDefaultsTest.rxTestGetSetEnabled( rxTest )

		local wfCatalog = createFakeWFCatalog( rxTest )
		local catalogDocId = wfCatalog:ozCatalogId()

		rxTest:waitFor( wfCatalog:docStore():setDocValue( {
			_id = catalogDocId,
			type = "catalog",
			subtype = "lightroom",
		} ) )

		rxTest:expectSingleValue( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'getEditDefaultsEnabled', wfCatalog ):take( 1 ), false )

		rxTest:waitFor( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'setEditDefaultsEnabled', wfCatalog, true ) )

		rxTest:expectSingleValue( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'getEditDefaultsEnabled', wfCatalog ):take( 1 ), true )

		-- disable again
		rxTest:waitFor( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'setEditDefaultsEnabled', wfCatalog, false ) )

		rxTest:expectSingleValue( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'getEditDefaultsEnabled', wfCatalog ):take( 1 ), false )

		-- enable again
		rxTest:waitFor( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'setEditDefaultsEnabled', wfCatalog, true ) )

		rxTest:expectSingleValue( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'getEditDefaultsEnabled', wfCatalog ):take( 1 ), true )

	end

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

	function WFCatEditDefaultsTest.rxTestGetSetDefaultImportPreset( rxTest )

		local wfCatalog = createFakeWFCatalog( rxTest )
		local catalogDocId = wfCatalog:ozCatalogId()

		rxTest:waitFor( wfCatalog:docStore():setDocValue( {
			_id = catalogDocId,
			type = "catalog",
			subtype = "lightroom",
		} ) )

		-- default import preset not yet set, expect nil
		rxTest:expectSingleValue( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'getDefaultImportPreset', wfCatalog ):take( 1 ), nil )

		rxTest:waitFor( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'setDefaultImportPreset', wfCatalog, "My Custom Preset", "B0ACA932B5E01F84C502D0CD225EDCFB" ) )

		-- add default import preset and implicitly the "enabled" key
		rxTest:expectSingleValue( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'getDefaultImportPreset', wfCatalog ):take( 1 ), {
				digest = "B0ACA932B5E01F84C502D0CD225EDCFB",
				name = "My Custom Preset",
			} )

		rxTest:expectSingleValue( wfCatalog:docStore():docValue( catalogDocId )
			:map( mapAwayCruft ),
			 {
				_id = catalogDocId,
				settings = {
					universal = {
						editDefaults = {
							cameras = {
								default = {
									digest = "B0ACA932B5E01F84C502D0CD225EDCFB",
									name = "My Custom Preset",
								},
							},
							enabled = true,
						}
					}
				},
				subtype = "lightroom",
				type = "catalog",
			})

		-- disable
		rxTest:waitFor( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'setEditDefaultsEnabled', wfCatalog, false ) )

		-- check that the default import preset is gone, and with it the whole cameras section
		rxTest:expectSingleValue( wfCatalog:docStore():docValue( catalogDocId )
			:map( mapAwayCruft ),
			 {
				_id = catalogDocId,
				settings = {
					universal = {
						editDefaults = {
							enabled = false,
						}
					}
				},
				subtype = "lightroom",
				type = "catalog",
			})

	end
	--------------------------------------------------------------------------------

	function WFCatEditDefaultsTest.rxTestGetEditDefaultsEnabledWithImportPreset( rxTest )

		local wfCatalog = createFakeWFCatalog( rxTest )
		local catalogDocId = wfCatalog:ozCatalogId()

		rxTest:waitFor( wfCatalog:docStore():setDocValue( {
			_id = catalogDocId,
			type = "catalog",
			subtype = "lightroom",
		} ) )

			-- editFefault and default import preset not yet set, expect nil

		rxTest:expectSingleValue( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'getEditDefaultsEnabledWithImportPreset', wfCatalog ):take( 1 ), {
				editDefaultsEnabled = false,
				defaultImportPreset = nil
			} )

		rxTest:waitFor( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'setEditDefaultsEnabled', wfCatalog, true ) )

		rxTest:expectSingleValue( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'getEditDefaultsEnabledWithImportPreset', wfCatalog ):take( 1 ), {
				editDefaultsEnabled = true,
				defaultImportPreset = nil
			} )

		rxTest:waitFor( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'setDefaultImportPreset', wfCatalog, "My Custom Preset", "B0ACA932B5E01F84C502D0CD225EDCFB" ) )

		rxTest:expectSingleValue( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'getEditDefaultsEnabledWithImportPreset', wfCatalog ):take( 1 ), {
				editDefaultsEnabled = true,
				defaultImportPreset = {
					digest = "B0ACA932B5E01F84C502D0CD225EDCFB",
					name = "My Custom Preset"
				}
			} )

		rxTest:waitFor( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'setEditDefaultsEnabled', wfCatalog, false ) )

		rxTest:expectSingleValue( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'getEditDefaultsEnabledWithImportPreset', wfCatalog ):take( 1 ), {
				editDefaultsEnabled = false,
				defaultImportPreset = nil } )

	end

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

	function WFCatEditDefaultsTest.rxTestAddRemovePresetByCameraModel( rxTest )

		local wfCatalog = createFakeWFCatalog( rxTest )
		local catalogDocId = wfCatalog:ozCatalogId()

		rxTest:waitFor( wfCatalog:docStore():setDocValue( {
			_id = catalogDocId,
			type = "catalog",
			subtype = "lightroom",
		} ) )

		rxTest:expectSingleValue( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'getEditDefaultsEnabled', wfCatalog ):take ( 1 ), false )

		rxTest:waitFor( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'setEditDefaultsEnabled', wfCatalog, true ) )

		rxTest:waitFor( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'setDefaultImportPreset', wfCatalog, "My Custom Preset", "B0ACA932B5E01F84C502D0CD225EDCFB" ) )

		rxTest:expectSingleValue( wfCatalog:docStore():docValue( catalogDocId )
			:map( mapAwayCruft ),
			 {
				_id = catalogDocId,
				settings = {
					universal = {
						editDefaults = {
							cameras = {
								default = {
									digest = "B0ACA932B5E01F84C502D0CD225EDCFB",
									name = "My Custom Preset",
								},
							},
							enabled = true,
						}
					}
				},
				subtype = "lightroom",
				type = "catalog",
			})

		-- disable enabled flag again, to see if setPresetForCameraModel() preserves the flag
		rxTest:waitFor( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'setEditDefaultsEnabled', wfCatalog, false ) )

		-- import preset for Canon5DMkIV not yet set, expect nil
		rxTest:expectSingleValue( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'getPresetForCameraModel', wfCatalog, "Canon5DMkIV" ):take( 1 ), nil )

		rxTest:waitFor( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'setPresetForCameraModel', wfCatalog, "Canon5DMkIV", "Canon EOS 5D Mark IV Camera Portrait", "54650A341B5B5CCAE8442D0B43A92BCE" ) )

		rxTest:waitFor( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'setPresetForCameraModel', wfCatalog, "PanasonicDCZS200", "Preset for ZS200", "16AA93D27ADA5E430D15f3D0B7BF4CB5" ) )

		rxTest:expectSingleValue( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'getPresetForCameraModel', wfCatalog, "Canon5DMkIV" ):take( 1 ), {
				digest = "54650A341B5B5CCAE8442D0B43A92BCE",
				name = "Canon EOS 5D Mark IV Camera Portrait",
			} )

		rxTest:expectSingleValue( wfCatalog:docStore():docValue( catalogDocId )
		:map( mapAwayCruft ),
		 {
			_id = catalogDocId,
			settings = {
				universal = {
					editDefaults = {
						cameras = {
							Canon5DMkIV = {
								default = {
									digest = "54650A341B5B5CCAE8442D0B43A92BCE",
									name = "Canon EOS 5D Mark IV Camera Portrait"
								}
							},
							PanasonicDCZS200 = {
								default = {
									digest = "16AA93D27ADA5E430D15f3D0B7BF4CB5",
									name = "Preset for ZS200"
								}
							},
						},
						enabled = false,
					}
				}
			},
			subtype = "lightroom",
			type = "catalog",
		})

		-- reenable enabled flag again
		rxTest:waitFor( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'setEditDefaultsEnabled', wfCatalog, true ) )

		rxTest:waitFor( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'removePresetForCameraModel', wfCatalog, "PanasonicDCZS200" ) )

		rxTest:expectSingleValue( wfCatalog:docStore():docValue( catalogDocId )
		:map( mapAwayCruft ),
		 {
			_id = catalogDocId,
			settings = {
				universal = {
					editDefaults = {
						cameras = {
							Canon5DMkIV = {
								default = {
									digest = "54650A341B5B5CCAE8442D0B43A92BCE",
									name = "Canon EOS 5D Mark IV Camera Portrait"
								}
							},
						},
						enabled = true,
					}
				}
			},
			subtype = "lightroom",
			type = "catalog",
		})

		-- disable
		rxTest:waitFor( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'setEditDefaultsEnabled', wfCatalog, false ) )

		-- check if value for cameras table is preserved
		rxTest:expectSingleValue( wfCatalog:docStore():docValue( catalogDocId )
		:map( mapAwayCruft ),
		 {
			_id = catalogDocId,
			settings = {
				universal = {
					editDefaults = {
						cameras = {
							Canon5DMkIV = {
								default = {
									digest = "54650A341B5B5CCAE8442D0B43A92BCE",
									name = "Canon EOS 5D Mark IV Camera Portrait"
								}
							},
						},
						enabled = false,
					}
				}
			},
			subtype = "lightroom",
			type = "catalog",
		})

		-- remove second entry
		rxTest:waitFor( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'removePresetForCameraModel', wfCatalog, "Canon5DMkIV" ) )

		-- cameras section should be completley gone
		rxTest:expectSingleValue( wfCatalog:docStore():docValue( catalogDocId )
		:map( mapAwayCruft ),
		 {
			_id = catalogDocId,
			settings = {
				universal = {
					editDefaults = {
						enabled = false,
					}
				}
			},
			subtype = "lightroom",
			type = "catalog",
		})

	end

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

	function WFCatEditDefaultsTest.rxTestListPresetByCameraModel( rxTest )

		local wfCatalog = createFakeWFCatalog( rxTest )
		local catalogDocId = wfCatalog:ozCatalogId()

		rxTest:waitFor( wfCatalog:docStore():setDocValue( {
			_id = catalogDocId,
			type = "catalog",
			subtype = "lightroom",
		} ) )

		rxTest:expectSingleValue( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'getEditDefaultsEnabled', wfCatalog ):take( 1 ), false )

		rxTest:waitFor( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'setEditDefaultsEnabled', wfCatalog, true ) )

		rxTest:waitFor( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'setDefaultImportPreset', wfCatalog, "My Custom Preset", "B0ACA932B5E01F84C502D0CD225EDCFB" ) )

		-- presetListByCameraModel not yet set, expect empty list
		rxTest:expectSingleValue( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'listPresetsByCameraModel', wfCatalog ):take( 1 ), {} )

		rxTest:waitFor( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'setPresetForCameraModel', wfCatalog, "Canon5DMkIV", "Canon EOS 5D Mark IV Camera Portrait", "54650A341B5B5CCAE8442D0B43A92BCE" ) )

		rxTest:waitFor( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'setPresetForCameraModel', wfCatalog, "PanasonicDCZS200", "Preset for ZS200", "16AA93D27ADA5E430D15f3D0B7BF4CB5" ) )

		rxTest:expectSingleValue( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'getPresetForCameraModel', wfCatalog, "Canon5DMkIV" ):take( 1 ), {
				digest = "54650A341B5B5CCAE8442D0B43A92BCE",
				name = "Canon EOS 5D Mark IV Camera Portrait",
			} )

		rxTest:expectSingleValue( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'listPresetsByCameraModel', wfCatalog ):take( 1 ), {
				Canon5DMkIV = {
					digest = "54650A341B5B5CCAE8442D0B43A92BCE",
					name = "Canon EOS 5D Mark IV Camera Portrait"
				},
				PanasonicDCZS200 = {
					digest = "16AA93D27ADA5E430D15f3D0B7BF4CB5",
					name = "Preset for ZS200"
				},
			} )


	end

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

	function WFCatEditDefaultsTest.rxTestOngoingEditDefaults( rxTest )

		local wfCatalog = createFakeWFCatalog( rxTest )
		local catalogDocId = wfCatalog:ozCatalogId()

		rxTest:waitFor( wfCatalog:docStore():setDocValue( {
			_id = catalogDocId,
			type = "catalog",
			subtype = "lightroom",
		} ) )

		local observerGetDefaultsEnabled = rxTest:observe( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'getEditDefaultsEnabled', wfCatalog ) )
		local observerGetDefaultImportPreset = rxTest:observe( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'getDefaultImportPreset', wfCatalog ) )
		local observerGetEditDefaultsEnabledWithDefaultImportPreset = rxTest:observe( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'getEditDefaultsEnabledWithImportPreset', wfCatalog ) )
		local observerGetPresetForCameraModel = rxTest:observe( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'getPresetForCameraModel', wfCatalog, "Canon5DMkIV" ) )
		local observerListPresetByCameraModel = rxTest:observe( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'listPresetsByCameraModel', wfCatalog ) )

		--
		rxTest:waitFor( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'setEditDefaultsEnabled', wfCatalog, true ) )

		observerGetDefaultsEnabled:expectDataWithinTime( 1, true )
		observerGetDefaultImportPreset:expectDataWithinTime( 1, nil )
		observerGetEditDefaultsEnabledWithDefaultImportPreset:expectDataWithinTime(1, {
			editDefaultsEnabled = true,
			defaultImportPreset = nil
		} )
		observerGetPresetForCameraModel:expectDataWithinTime( 1, nil )
		observerListPresetByCameraModel:expectDataWithinTime( 1, {} )

		--
		rxTest:waitFor( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'setDefaultImportPreset', wfCatalog, "My Custom Preset", "B0ACA932B5E01F84C502D0CD225EDCFB" ) )

		observerGetDefaultsEnabled:expectDataWithinTime( 1, true )
		observerGetDefaultImportPreset:expectDataWithinTime( 1, {
			digest = "B0ACA932B5E01F84C502D0CD225EDCFB",
			name = "My Custom Preset",
		} )
		observerGetEditDefaultsEnabledWithDefaultImportPreset:expectDataWithinTime(1, {
			editDefaultsEnabled = true,
			defaultImportPreset =  {
				digest = "B0ACA932B5E01F84C502D0CD225EDCFB",
				name = "My Custom Preset",
			}
		} )
		observerGetPresetForCameraModel:expectDataWithinTime( 1, nil )
		observerListPresetByCameraModel:expectDataWithinTime( 1, {} )

		--
		rxTest:waitFor( callFunctionOrSubmodel(
					rxTest, wfCatalog,
					'WFCatEditDefaults',
					'setPresetForCameraModel', wfCatalog, "Canon5DMkIV", "Canon EOS 5D Mark IV Camera Portrait", "54650A341B5B5CCAE8442D0B43A92BCE" ) )

		observerGetDefaultsEnabled:expectDataWithinTime( 1, true )
		observerGetDefaultImportPreset:expectDataWithinTime( 1, {
			digest = "B0ACA932B5E01F84C502D0CD225EDCFB",
			name = "My Custom Preset",
		} )
		observerGetEditDefaultsEnabledWithDefaultImportPreset:expectDataWithinTime(1, {
			editDefaultsEnabled = true,
			defaultImportPreset =  {
				digest = "B0ACA932B5E01F84C502D0CD225EDCFB",
				name = "My Custom Preset",
			}
		} )
		observerGetPresetForCameraModel:expectDataWithinTime( 1, {
			digest = "54650A341B5B5CCAE8442D0B43A92BCE",
			name = "Canon EOS 5D Mark IV Camera Portrait"
		} )
		observerListPresetByCameraModel:expectDataWithinTime( 1, {
			Canon5DMkIV = {
				digest = "54650A341B5B5CCAE8442D0B43A92BCE",
				name = "Canon EOS 5D Mark IV Camera Portrait"
			}
		} )


	end
	------------------------------------------------------------------------------

	return maybeExistingTestClass and WFCatEditDefaultsTest
			or WFRxTestCase.wrapSuite( 'WFCatEditDefaultsTest', WFCatEditDefaultsTest )

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

end 
