From a19b5c4e056a39c60cfccfff3bbce8267d52d1df Mon Sep 17 00:00:00 2001
From: Federico Maccaroni <fedemkr@gmail.com>
Date: Thu, 15 Dec 2022 13:03:34 -0300
Subject: [PATCH] EC-842 Delete items that are not included in the sync to the
 watch (#2242)

---
 .../Services/CipherService.swift              | 49 ++++++++++++-------
 1 file changed, 31 insertions(+), 18 deletions(-)

diff --git a/src/watchOS/bitwarden/bitwarden WatchKit Extension/Services/CipherService.swift b/src/watchOS/bitwarden/bitwarden WatchKit Extension/Services/CipherService.swift
index 6328ae40c..b5f7407a3 100644
--- a/src/watchOS/bitwarden/bitwarden WatchKit Extension/Services/CipherService.swift	
+++ b/src/watchOS/bitwarden/bitwarden WatchKit Extension/Services/CipherService.swift	
@@ -41,25 +41,28 @@ extension CipherService: CipherServiceProtocol {
         }
     }
     
-    func saveCiphers(_ ciphers: [Cipher], completionHandler: @escaping () -> Void){
-        dbHelper.insertBatch("CipherEntity", items: ciphers) { item, context in
-            guard let cipher = item as! Cipher? else { return [:] }
-            let c = cipher.toCipherEntity(moContext: context)
-            guard let data = try? JSONEncoder().encode(c) else
-            {
-                Log.e("Error converting to data")
-                return [:]
-            }
-            
-            guard let cipherDict = try? JSONSerialization.jsonObject(with: data, options: []) as? [String : Any ] else
-            {
-                Log.e("Error converting json data to dict")
-                return [:]
-            }
-            return cipherDict
+    func saveCiphers(_ ciphers: [Cipher], completionHandler: @escaping () -> Void) {
+        let cipherIds = ciphers.map { $0.id }
+        deleteAll(ciphers[0].userId, notIn: cipherIds) {
+            self.dbHelper.insertBatch("CipherEntity", items: ciphers) { item, context in
+                guard let cipher = item as! Cipher? else { return [:] }
+                let c = cipher.toCipherEntity(moContext: context)
+                guard let data = try? JSONEncoder().encode(c) else
+                {
+                    Log.e("Error converting to data")
+                    return [:]
+                }
+                
+                guard let cipherDict = try? JSONSerialization.jsonObject(with: data, options: []) as? [String : Any ] else
+                {
+                    Log.e("Error converting json data to dict")
+                    return [:]
+                }
+                return cipherDict
 
-        } completionHandler: {
-            completionHandler()
+            } completionHandler: {
+                completionHandler()
+            }
         }
     }
     
@@ -67,4 +70,14 @@ extension CipherService: CipherServiceProtocol {
         let predicate = withUserId == nil ? nil : NSPredicate(format: "userId = %@", withUserId!)
         dbHelper.deleteAll("CipherEntity", predicate: predicate, completionHandler: completionHandler)
     }
+    
+    func deleteAll(_ withUserId: String? = nil, notIn: [String], completionHandler: @escaping () -> Void) {
+        var predicateList : [NSPredicate] = []
+        if let userId = withUserId {
+            predicateList.append(NSPredicate(format: "userId = %@", userId))
+        }
+        predicateList.append(NSPredicate(format: "NOT (id in %@)", notIn))
+        let predicate = NSCompoundPredicate(type: .and, subpredicates: predicateList)
+        dbHelper.deleteAll("CipherEntity", predicate: predicate, completionHandler: completionHandler)
+    }
 }