/*
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance with the License. You may obtain a
 * copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */

package org.apache.geode.security;

import java.util.Properties;
import java.util.concurrent.atomic.AtomicReference;

import org.apache.geode.distributed.DistributedMember;

/**
 * this is used in conjunction with ExpirableSecurityManager. It will create a new set of
 * credentials every time getCredentials are called, and they will always be authenticated
 * and authorized by the ExpirableSecurityManager.
 *
 * make sure reset is called after each test to clean things up.
 */
public class UpdatableUserAuthInitialize implements AuthInitialize {
  // use static field for ease of testing since there is only one instance of this in each VM
  private static final AtomicReference<String> user = new AtomicReference<>();
  // this is used to simulate a slow client in milliseconds
  private static final AtomicReference<Long> waitTime = new AtomicReference<>(0L);

  @Override
  public Properties getCredentials(Properties securityProps, DistributedMember server,
      boolean isPeer) throws AuthenticationFailedException {
    Properties credentials = new Properties();
    credentials.put("security-username", user.get());
    credentials.put("security-password", user.get());

    Long timeToWait = waitTime.get();
    if (timeToWait < 0) {
      throw new AuthenticationFailedException("Something wrong happened.");
    } else if (timeToWait > 0) {
      try {
        Thread.sleep(timeToWait);
      } catch (InterruptedException e) {
        throw new RuntimeException(e.getMessage(), e);
      }
    }
    return credentials;
  }

  public static String getUser() {
    return user.get();
  }

  public static void setUser(String newValue) {
    user.set(newValue);
  }

  public static void setWaitTime(long newValue) {
    waitTime.set(newValue);
  }

  public static void reset() {
    user.set(null);
    waitTime.set(0L);
  }
}

@@ -853,60 +853,43 @@
 es;%0A
+%0A
 import 
-java.util.concurrent.atomic.AtomicReference;%0A
+org.apache.geode.LogWriter;
 %0Aimp
@@ -1318,16 +1318,175 @@
 alize %7B%0A
+  private static final String TEST_UPDATABLE_USER = %22test.updatable.user%22;%0A  private static final String TEST_UPDATABLE_WAIT_TIME = %22test.updatable.waitTime%22;%0A
   // use
@@ -1585,52 +1585,22 @@
 ate 
-static final AtomicReference%3C
 String
-%3E
  user = 
 new 
@@ -1599,31 +1599,10 @@
 r = 
-new AtomicReference%3C%3E()
+%22%22
 ;%0A  
@@ -1673,80 +1673,273 @@
 ate 
-static final AtomicReference%3CLong%3E waitTime = new AtomicReference%3C%3E(0L);
+Long waitTime = 0L;%0A%0A  @Override%0A  public void init(LogWriter systemLogger, LogWriter securityLogger)%0A      throws AuthenticationFailedException %7B%0A    user = System.getProperty(TEST_UPDATABLE_USER, %22%22);%0A    waitTime = Long.getLong(TEST_UPDATABLE_WAIT_TIME, 0L);%0A  %7D
 %0A%0A  
@@ -2188,22 +2188,16 @@
 e%22, user
-.get()
 );%0A    c
@@ -2240,22 +2240,16 @@
 user
-.get()
 );%0A%0A    
 Long
@@ -2248,60 +2248,20 @@
     
-Long timeToWait = waitTime.get();%0A    if (timeToWait
+if (waitTime
  %3C 0
@@ -2355,26 +2355,24 @@
 lse if (
-timeToWait
+waitTime
  %3E 0) %7B%0A
@@ -2408,18 +2408,16 @@
 eep(
-timeToWait
+waitTime
 );%0A 
@@ -2574,116 +2574,84 @@
 tic 
-String getUser() %7B%0A    return user.get();%0A  %7D%0A%0A  public static void setUser(String newValue) %7B%0A    user.set(
+void setUser(String newValue) %7B%0A    System.setProperty(TEST_UPDATABLE_USER, 
 newV
@@ -2720,29 +2720,61 @@
     
-waitTime.set(
+System.setProperty(TEST_UPDATABLE_WAIT_TIME, 
 newValue
 );%0A 
@@ -2761,32 +2761,37 @@
 T_TIME, newValue
+ + %22%22
 );%0A  %7D%0A%0A  public
@@ -2821,43 +2821,100 @@
     
-user.set(null);%0A    waitTime.set(0L
+System.clearProperty(TEST_UPDATABLE_USER);%0A    System.clearProperty(TEST_UPDATABLE_WAIT_TIME
 );%0A 

refactor test AuthInit to not use static field for credentials. (#6922)