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

LrClassicDevelopSettingsTest.lua

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

ADOBE CONFIDENTIAL
------------------
Copyright 2024 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'

local Rx = require 'Rx'

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

	-- WF.core.os
local WFPlatformInfo = require "WFPlatformInfo"

	-- WF.core.utils
local KSIdGenerator = require 'KSIdGenerator'
local WFCapabilities = require 'WFCapabilities'

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

local LrClassicDevelopSettingsTest = {}

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

function LrClassicDevelopSettingsTest.rxTestSetCameraRawSettings_testSerially( rxTest )

  WFCapabilities.setCapability( 'LrClassic_avoidEmptyContentUpdate', 'true' )

  rxTest:finally( function()
		WFCapabilities.setCapability( 'LrClassic_avoidEmptyContentUpdate', nil )
	end )

	local catalog = WFCatMockCatalog.createFakeWFCatalog( rxTest )

	local imageAssetId1 = KSIdGenerator.uuidInLowercaseHex()

	local croppedWidth = 1920
	local croppedHeight = 1080
	local needsUpdateAISettings = true
	local auxInfo = {}
	local maybeLensProfileDigest = nil
	local maybeCameraProfileFingerprint = nil -- "CB53843054696C00239B1180057888D3"
	local maybeIsFallbackProfile = false
	local maybeCameraProfileDigest = nil -- "9C057227216BE688434471F22E5E736D"
	local maybeCameraProfileName = nil -- "Adobe Standard"
	local cameraModel = "Canon EOS 20D"
	local tiffOrientation = 1
	local isReset = false
	local isVideo = false
	local temporal = nil
	local xmpSettings = [[
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 7.0-c000 1.000000, 0000/00/00-00:00:00        ">
 <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
  <rdf:Description rdf:about=""
    xmlns:crs="http://ns.adobe.com/camera-raw-settings/1.0/"
   crs:Version="17.0"
   crs:ProcessVersion="15.4"
   crs:WhiteBalance="Custom"
   crs:Temperature="2000"
   crs:Tint="-150"
   crs:Exposure2012="0.00"
   crs:Contrast2012="0"
   crs:Highlights2012="0"
   crs:Shadows2012="0"
   crs:Whites2012="0"
   crs:Blacks2012="0"
   crs:Texture="0"
   crs:Clarity2012="0"
   crs:Dehaze="0"
   crs:Vibrance="0"
   crs:Saturation="0"
   crs:ParametricShadows="0"
   crs:ParametricDarks="0"
   crs:ParametricLights="0"
   crs:ParametricHighlights="0"
   crs:ParametricShadowSplit="25"
   crs:ParametricMidtoneSplit="50"
   crs:ParametricHighlightSplit="75"
   crs:Sharpness="40"
   crs:SharpenRadius="+1.0"
   crs:SharpenDetail="25"
   crs:SharpenEdgeMasking="0"
   crs:LuminanceSmoothing="0"
   crs:ColorNoiseReduction="25"
   crs:ColorNoiseReductionDetail="50"
   crs:ColorNoiseReductionSmoothness="50"
   crs:HueAdjustmentRed="0"
   crs:HueAdjustmentOrange="0"
   crs:HueAdjustmentYellow="0"
   crs:HueAdjustmentGreen="0"
   crs:HueAdjustmentAqua="0"
   crs:HueAdjustmentBlue="0"
   crs:HueAdjustmentPurple="0"
   crs:HueAdjustmentMagenta="0"
   crs:SaturationAdjustmentRed="0"
   crs:SaturationAdjustmentOrange="0"
   crs:SaturationAdjustmentYellow="0"
   crs:SaturationAdjustmentGreen="0"
   crs:SaturationAdjustmentAqua="0"
   crs:SaturationAdjustmentBlue="0"
   crs:SaturationAdjustmentPurple="0"
   crs:SaturationAdjustmentMagenta="0"
   crs:LuminanceAdjustmentRed="0"
   crs:LuminanceAdjustmentOrange="0"
   crs:LuminanceAdjustmentYellow="0"
   crs:LuminanceAdjustmentGreen="0"
   crs:LuminanceAdjustmentAqua="0"
   crs:LuminanceAdjustmentBlue="0"
   crs:LuminanceAdjustmentPurple="0"
   crs:LuminanceAdjustmentMagenta="0"
   crs:SplitToningShadowHue="0"
   crs:SplitToningShadowSaturation="0"
   crs:SplitToningHighlightHue="0"
   crs:SplitToningHighlightSaturation="0"
   crs:SplitToningBalance="0"
   crs:ColorGradeMidtoneHue="0"
   crs:ColorGradeMidtoneSat="0"
   crs:ColorGradeShadowLum="0"
   crs:ColorGradeMidtoneLum="0"
   crs:ColorGradeHighlightLum="0"
   crs:ColorGradeBlending="50"
   crs:ColorGradeGlobalHue="0"
   crs:ColorGradeGlobalSat="0"
   crs:ColorGradeGlobalLum="0"
   crs:AutoLateralCA="0"
   crs:LensProfileEnable="0"
   crs:LensManualDistortionAmount="0"
   crs:VignetteAmount="0"
   crs:DefringePurpleAmount="0"
   crs:DefringePurpleHueLo="30"
   crs:DefringePurpleHueHi="70"
   crs:DefringeGreenAmount="0"
   crs:DefringeGreenHueLo="40"
   crs:DefringeGreenHueHi="60"
   crs:PerspectiveUpright="0"
   crs:PerspectiveVertical="0"
   crs:PerspectiveHorizontal="0"
   crs:PerspectiveRotate="0.0"
   crs:PerspectiveAspect="0"
   crs:PerspectiveScale="100"
   crs:PerspectiveX="0.00"
   crs:PerspectiveY="0.00"
   crs:GrainAmount="0"
   crs:PostCropVignetteAmount="0"
   crs:ShadowTint="0"
   crs:RedHue="0"
   crs:RedSaturation="0"
   crs:GreenHue="0"
   crs:GreenSaturation="0"
   crs:BlueHue="0"
   crs:BlueSaturation="0"
   crs:HDREditMode="0"
   crs:OverrideLookVignette="False"
   crs:ToneCurveName2012="Linear"
   crs:CameraProfile="Adobe Standard"
   crs:CameraProfileDigest="9C057227216BE688434471F22E5E736D"
   crs:HasSettings="True"
   crs:AlreadyApplied="False"
   crs:CropTop="0"
   crs:CropLeft="0"
   crs:CropBottom="1"
   crs:CropRight="1"
   crs:CropAngle="0"
   crs:CropConstrainToWarp="0"
   crs:CropConstrainToUnitSquare="1"
   crs:HasCrop="False">
   <crs:ToneCurvePV2012>
    <rdf:Seq>
     <rdf:li>0, 0</rdf:li>
     <rdf:li>255, 255</rdf:li>
    </rdf:Seq>
   </crs:ToneCurvePV2012>
   <crs:ToneCurvePV2012Red>
    <rdf:Seq>
     <rdf:li>0, 0</rdf:li>
     <rdf:li>255, 255</rdf:li>
    </rdf:Seq>
   </crs:ToneCurvePV2012Red>
   <crs:ToneCurvePV2012Green>
    <rdf:Seq>
     <rdf:li>0, 0</rdf:li>
     <rdf:li>255, 255</rdf:li>
    </rdf:Seq>
   </crs:ToneCurvePV2012Green>
   <crs:ToneCurvePV2012Blue>
    <rdf:Seq>
     <rdf:li>0, 0</rdf:li>
     <rdf:li>255, 255</rdf:li>
    </rdf:Seq>
   </crs:ToneCurvePV2012Blue>
   <crs:PointColors>
    <rdf:Seq>
     <rdf:li>-1.000000, -1.000000, -1.000000, -1.000000, -1.000000, -1.000000, -1.000000, -1.000000, -1.000000, -1.000000, -1.000000, -1.000000, -1.000000, -1.000000, -1.000000, -1.000000, -1.000000, -1.000000, -1.000000</rdf:li>
    </rdf:Seq>
   </crs:PointColors>
   <crs:Look>
    <rdf:Description
     crs:Name="Adobe Color"
     crs:Amount="1"
     crs:UUID="B952C231111CD8E0ECCF14B86BAA7077"
     crs:SupportsAmount="false"
     crs:SupportsMonochrome="false"
     crs:SupportsOutputReferred="false">
    <crs:Group>
     <rdf:Alt>
      <rdf:li xml:lang="x-default">Profiles</rdf:li>
     </rdf:Alt>
    </crs:Group>
    <crs:Parameters>
     <rdf:Description
      crs:Version="17.0"
      crs:ProcessVersion="15.4"
      crs:ConvertToGrayscale="False"
      crs:CameraProfile="Adobe Standard"
      crs:LookTable="E1095149FDB39D7A057BAB208837E2E1">
     <crs:ToneCurvePV2012>
      <rdf:Seq>
       <rdf:li>0, 0</rdf:li>
       <rdf:li>22, 16</rdf:li>
       <rdf:li>40, 35</rdf:li>
       <rdf:li>127, 127</rdf:li>
       <rdf:li>224, 230</rdf:li>
       <rdf:li>240, 246</rdf:li>
       <rdf:li>255, 255</rdf:li>
      </rdf:Seq>
     </crs:ToneCurvePV2012>
     <crs:ToneCurvePV2012Red>
      <rdf:Seq>
       <rdf:li>0, 0</rdf:li>
       <rdf:li>255, 255</rdf:li>
      </rdf:Seq>
     </crs:ToneCurvePV2012Red>
     <crs:ToneCurvePV2012Green>
      <rdf:Seq>
       <rdf:li>0, 0</rdf:li>
       <rdf:li>255, 255</rdf:li>
      </rdf:Seq>
     </crs:ToneCurvePV2012Green>
     <crs:ToneCurvePV2012Blue>
      <rdf:Seq>
       <rdf:li>0, 0</rdf:li>
       <rdf:li>255, 255</rdf:li>
      </rdf:Seq>
     </crs:ToneCurvePV2012Blue>
     </rdf:Description>
    </crs:Parameters>
    </rdf:Description>
   </crs:Look>
  </rdf:Description>
 </rdf:RDF>
</x:xmpmeta>
	]]

	local wfCatalogStream = Rx.Observable.just( catalog )
	local settingsModel = LrClassicDevelopSettings.setCameraRawSettings( wfCatalogStream )

	local observer = rxTest:observe( settingsModel.value )

	settingsModel.events:save( 1, imageAssetId1, isVideo, croppedWidth, croppedHeight,
								xmpSettings, auxInfo, needsUpdateAISettings,
								maybeLensProfileDigest,
								maybeCameraProfileFingerprint,
								maybeIsFallbackProfile,
								maybeCameraProfileDigest,
								maybeCameraProfileName,
								cameraModel, tiffOrientation,
								temporal, isReset )

	rxTest:expectSingleValue(
		LrClassicDevelopSettings.waitForPendingDevelopSettingsSaveForAssetIds( { imageAssetId1 } ),
		true )

	observer:expectDataWithinTime( 1, { 1, imageAssetId1 } )

	local imageAsset1MostRecentRevId

	rxTest:expectSingleValue( catalog:docStore():docValue( imageAssetId1 )
			:map( function( imageAsset1DocValue )
				imageAsset1MostRecentRevId = imageAsset1DocValue._revId
				return imageAsset1DocValue
			end )
			:pluck( 'develop', 'userUpdated' )
			:map( type ),
		'string' )

	rxTest:expectSingleValue( catalog:docStore():docValue( imageAssetId1 )
			:pluck( 'develop', 'needsUpdateAISettings' ),
		true )

	-- Make some change and see if revision is updated

	croppedWidth = 1000
	croppedHeight = 1000
	needsUpdateAISettings = false

	settingsModel.events:save( 2, imageAssetId1, isVideo, croppedWidth, croppedHeight,
								xmpSettings, auxInfo, needsUpdateAISettings,
								maybeLensProfileDigest,
								maybeCameraProfileFingerprint,
								maybeIsFallbackProfile,
								maybeCameraProfileDigest,
								maybeCameraProfileName,
								cameraModel, tiffOrientation,
								temporal, isReset )

	observer:expectDataWithinTime( 1, { 2, imageAssetId1 } )

	rxTest:expectSingleValue( catalog:docStore():docValue( imageAssetId1 )
			:map( function( imageAsset1DocValue )
				
				local revIdHasChanged = imageAsset1DocValue._revId ~= imageAsset1MostRecentRevId
				imageAsset1MostRecentRevId = imageAsset1DocValue._revId

				return revIdHasChanged 
					and imageAsset1DocValue.develop.croppedWidth == 1000
					and imageAsset1DocValue.develop.croppedWidth == 1000
					and imageAsset1DocValue.develop.needsUpdateAISettings == nil

			end ),
		true )

	-- No new change, the revId should remain the same

	settingsModel.events:save( 3, imageAssetId1, isVideo, croppedWidth, croppedHeight,
								xmpSettings, auxInfo, needsUpdateAISettings,
								maybeLensProfileDigest,
								maybeCameraProfileFingerprint,
								maybeIsFallbackProfile,
								maybeCameraProfileDigest,
								maybeCameraProfileName,
								cameraModel, tiffOrientation,
								temporal, isReset )

	observer:expectDataWithinTime( 1, { 3, imageAssetId1 } )

end

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

-- LrClassicDevelopSettingsTest is only used by LrD

if WFPlatformInfo.isMobile() then
	return {}
else
	return WFRxTestCase.wrapSuite( 'LrClassicDevelopSettingsTest', LrClassicDevelopSettingsTest )
end
