package ru.job4j.multithreading.users;

import net.jcip.annotations.GuardedBy;
import net.jcip.annotations.ThreadSafe;

import java.util.HashMap;
import java.util.Map;

@ThreadSafe
public class UserStorage {
    @GuardedBy("this")
    private final Map<Integer, User> storage = new HashMap<>();

    public boolean add (User user) {
        synchronized(storage) {
            boolean isAdd = false;
            if (!storage.containsKey(user.getId())) {
                storage.put(user.getId(), user);
                isAdd = true;
            }
            return isAdd;
        }
    }

    public synchronized boolean update(User user) {
        synchronized (storage) {
            boolean isUpdate = false;
            if (storage.containsKey(user.getId())) {
                User prevUser = storage.get(user.getId());
                prevUser.setAmount(user.getAmount() + prevUser.getAmount());
                storage.put(prevUser.getId(), prevUser);
                isUpdate = true;
            }
            return isUpdate;
        }
    }

    public synchronized boolean delete(User user) {
        synchronized (storage) {
            boolean isDelete = false;
            if (storage.containsKey(user.getId())) {
                storage.remove(user.getId());
                isDelete = true;
            }

            return isDelete;
        }
    }

    public boolean transfer(int fromId, int toId, int amount) {
        boolean isTransfer = false;
        if (storage.containsKey(fromId) && storage.containsKey(toId)) {
            User from = storage.get(fromId);
            User to = storage.get(toId);
            if (from.getAmount() >= amount) {
                synchronized(from) {
                    synchronized (to) {
                        from.setAmount(from.getAmount() - amount);
                        storage.put(fromId, from);
                        to.setAmount(to.getAmount() + amount);
                        storage.put(toId, to);
                        isTransfer = true;
                    }
                }
            }

        }
        return isTransfer;
    }

    public synchronized Map<Integer, User> getStorage() {
        return storage;
    }
}

@@ -221,12 +221,15 @@
 By(%22
-this
+storage
 %22)%0A 
@@ -593,37 +593,24 @@
 %0A    public 
-synchronized 
 boolean upda
@@ -1046,29 +1046,16 @@
  public 
-synchronized 
 boolean 
@@ -1283,33 +1283,32 @@
 ;%0A            %7D%0A
-%0A
             retu
@@ -1393,32 +1393,69 @@
 , int amount) %7B%0A
+        synchronized (storage) %7B%0A    
         boolean 
@@ -1466,32 +1466,36 @@
 ansfer = false;%0A
+    
         if (stor
@@ -1558,24 +1558,28 @@
             
+    
 User from = 
@@ -1607,24 +1607,28 @@
             
+ 
+   
 User to = st
@@ -1640,24 +1640,28 @@
 .get(toId);%0A
+    
             
@@ -1702,32 +1702,36 @@
                 
+    
 synchronized(fro
@@ -1726,16 +1726,17 @@
 hronized
+ 
 (from) %7B
@@ -1748,32 +1748,36 @@
                 
+    
 synchronized (to
@@ -1776,24 +1776,28 @@
 ized (to) %7B%0A
+    
             
@@ -1867,32 +1867,36 @@
                 
+   
+ 
 storage.put(from
@@ -1906,16 +1906,20 @@
  from);%0A
+    
         
@@ -1989,32 +1989,36 @@
                 
+    
 storage.put(toId
@@ -2048,16 +2048,20 @@
         
+   
+ 
 isTransf
@@ -2083,34 +2083,42 @@
                 
-%7D%0A
+    %7D%0A    
                 
@@ -2127,24 +2127,28 @@
             
+  
+  
 %7D%0A%0A        %7D
@@ -2138,34 +2138,42 @@
      %7D%0A%0A        
+   
+ 
 %7D%0A
+    
         return i
@@ -2191,92 +2191,13 @@
     
-%7D%0A%0A
     
-public synchronized Map%3CInteger, User%3E getStorage() %7B%0A        return storage;
+%7D
 %0A   

task 1104