// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.spring.cloud.autoconfigure.implementation.graph;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class ThreadInterruptedStatusRestoreTest {

    @Test
    void testThreadInterruptedRestoreFromAnotherThread() throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(1);
        Thread testThread = new TestThread(latch, true);
        testThread.setDaemon(true);
        testThread.start();
        TimeUnit.SECONDS.sleep(2L);
        testThread.interrupt();
        latch.await(5, TimeUnit.SECONDS);
        System.out.println(Thread.currentThread().getName() + ": begin assertion");
        Assertions.assertTrue(testThread.isInterrupted());
        System.out.println(Thread.currentThread().getName() + ": end assertion");
    }

    @Test
    void testThreadInterruptedNotRestoreFromAnotherThread() throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(1);
        Thread testThread = new TestThread(latch, false);
        testThread.setDaemon(true);
        testThread.start();
        TimeUnit.SECONDS.sleep(2L);
        testThread.interrupt();
        latch.await(5, TimeUnit.SECONDS);
        System.out.println(Thread.currentThread().getName() + ": begin assertion");
        Assertions.assertFalse(testThread.isInterrupted());
        System.out.println(Thread.currentThread().getName() + ": end assertion");
    }

    static class TestThread extends Thread {
        private final CountDownLatch latch;

        private final boolean restore;

        TestThread(CountDownLatch latch, boolean restore) {
            this.latch = latch;
            this.restore = restore;
        }

        @Override
        public void run() {
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException ex) {
                    System.out.println(Thread.currentThread().getName() + ": current thread was interrupted!");
                    if (restore) {
                        Thread.currentThread().interrupt();
                    }

                    latch.countDown();
                    someMethodConsumingTime();
                }
            }
        }

        private void someMethodConsumingTime() {
            long sum = 0;
            for (int i = 0; i < 10000; i++) {
                if (i % 2 != 0) {
                    sum++;
                }
            }

            System.out.println(Thread.currentThread().getName() + ": sum = " + sum);
        }
    }
}

@@ -486,32 +486,42 @@
 tDownLatch latch
+ForInWhile
  = new CountDown
@@ -530,32 +530,100 @@
 tch(1);%0A        
+CountDownLatch latchForInCatch = new CountDownLatch(1);%0A        Test
 Thread testThrea
@@ -646,16 +646,43 @@
 ad(latch
+ForInWhile, latchForInCatch
 , true);
@@ -758,33 +758,30 @@
     
-TimeUnit.SECONDS.sleep(2L
+latchForInWhile.await(
 );%0A 
@@ -828,37 +828,29 @@
 atch
-.await(5, TimeUnit.SECONDS
+ForInCatch.await(
 );%0A
+%0A
     
@@ -959,16 +959,17 @@
 ertTrue(
+(
 testThre
@@ -962,34 +962,38 @@
 True((testThread
-.i
+).getI
 sInterrupted());
@@ -1206,24 +1206,34 @@
 nLatch latch
+ForInWhile
  = new Count
@@ -1250,24 +1250,92 @@
 1);%0A        
+CountDownLatch latchForInCatch = new CountDownLatch(1);%0A        Test
 Thread testT
@@ -1362,16 +1362,43 @@
 ad(latch
+ForInWhile, latchForInCatch
 , false)
@@ -1475,33 +1475,30 @@
     
-TimeUnit.SECONDS.sleep(2L
+latchForInWhile.await(
 );%0A 
@@ -1545,37 +1545,29 @@
 atch
-.await(5, TimeUnit.SECONDS
+ForInCatch.await(
 );%0A
+%0A
     
@@ -1688,17 +1688,20 @@
 tThread.
-i
+getI
 sInterru
@@ -1794,24 +1794,25 @@
 n%22);%0A    %7D%0A%0A
+%0A
     static c
@@ -1886,16 +1886,80 @@
 ch latch
+ForInWhile;%0A        private final CountDownLatch latchForInCatch
 ;%0A%0A     
@@ -1991,16 +1991,55 @@
 restore;
+%0A        boolean isInterrupted = false;
 %0A%0A      
@@ -2071,16 +2071,58 @@
 ch latch
+ForInWhile, CountDownLatch latchForInCatch
 , boolea
@@ -2160,12 +2160,84 @@
 atch
- = l
+ForInWhile = latchForInWhile;%0A            this.latchForInCatch = latchForInC
 atch
@@ -2415,16 +2415,65 @@
   try %7B%0A
+                    latchForInWhile.countDown();%0A
         
@@ -2817,415 +2817,235 @@
     
-latch.countDown();%0A                    someMethodConsumingTime();%0A                %7D%0A            %7D%0A        %7D%0A%0A        private void someMethodConsumingTime() %7B%0A            long sum = 0;%0A            for (int i = 0; i %3C 10000; i++) %7B%0A                if (i %25 2 != 0) %7B%0A                    sum++;%0A                %7D%0A            %7D%0A%0A            System.out.println(Thread.currentThread().getName() + %22: sum = %22 + sum)
+this.isInterrupted = Thread.currentThread().isInterrupted();%0A                    latchForInCatch.countDown();%0A                %7D%0A            %7D%0A        %7D%0A%0A        boolean getIsInterrupted() %7B%0A            return this.isInterrupted
 ;%0A  

fix The Test Case for ThreadInterruptedStatusRestoreTest (#29034)