/*
 * 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.dubbo.rpc.protocol.dubbo.status;

import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.status.Status;
import org.apache.dubbo.common.store.DataStore;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

import java.util.concurrent.ThreadPoolExecutor;


public class ThreadPoolStatusCheckerTest {

    private ThreadPoolStatusChecker threadPoolStatusChecker;
    private Status status;

    @BeforeEach
    public void setUp() {
        threadPoolStatusChecker = new ThreadPoolStatusChecker();
        status = threadPoolStatusChecker.check();
    }

    @Test
    public void statusUnknownTest() {
        Assertions.assertEquals(status.getLevel(), Status.Level.UNKNOWN);
    }

    @Test
    public void statusOkTest() {
        int activeCount = 1;
        int maximumPoolSize = 3;
        String portKey = "8888";
        mockThreadPoolExecutor(activeCount, maximumPoolSize, portKey);

        Status status = threadPoolStatusChecker.check();

        Assertions.assertEquals(status.getLevel(), Status.Level.OK);
        Assertions.assertEquals(status.getMessage(), "Pool status:OK, max:" + maximumPoolSize + ", core:0, largest:0, active:" + activeCount + ", task:0, service port: " + portKey);
    }


    @Test
    public void statusWarnTest() {
        int activeCount = 1;
        int maximumPoolSize = 2;
        String portKey = "8888";
        mockThreadPoolExecutor(activeCount, maximumPoolSize, portKey);

        Status status = threadPoolStatusChecker.check();

        Assertions.assertEquals(status.getLevel(), Status.Level.WARN);
        Assertions.assertEquals(status.getMessage(), "Pool status:WARN, max:" + maximumPoolSize + ", core:0, largest:0, active:" + activeCount + ", task:0, service port: 8888");
    }

    private void mockThreadPoolExecutor(int activeCount, int maximumPoolSize, String portKey) {
        DataStore dataStore = ExtensionLoader.getExtensionLoader(DataStore.class).getDefaultExtension();

        ThreadPoolExecutor executor = Mockito.mock(ThreadPoolExecutor.class);
        Mockito.when(executor.getActiveCount()).thenReturn(activeCount);
        Mockito.when(executor.getMaximumPoolSize()).thenReturn(maximumPoolSize);

        dataStore.put(CommonConstants.EXECUTOR_SERVICE_COMPONENT_KEY, portKey, executor);
    }

}

@@ -1010,16 +1010,69 @@
 Status;%0A
+import org.apache.dubbo.common.status.StatusChecker;%0A
 import o
@@ -1187,20 +1187,19 @@
 i.Before
-Each
+All
 ;%0Aimport
@@ -1362,16 +1362,23 @@
 private 
+static 
 ThreadPo
@@ -1421,35 +1421,8 @@
 ker;
-%0A    private Status status;
 %0A%0A  
@@ -1434,12 +1434,11 @@
 fore
-Each
+All
 %0A   
@@ -1441,24 +1441,31 @@
 %0A    public 
+static 
 void setUp()
@@ -1504,13 +1504,26 @@
 er =
- new 
+%0A                (
 Thre
@@ -1545,116 +1545,205 @@
 cker
-();%0A        status = threadPoolStatusChecker.check();%0A    %7D%0A%0A    @Test%0A    public void statusUnknownTest() %7B
+) ExtensionLoader.getExtensionLoader(StatusChecker.class).getExtension(%22threadpool%22);%0A    %7D%0A%0A    @Test%0A    public void statusUnknownTest() %7B%0A        Status status = threadPoolStatusChecker.check();
 %0A   
@@ -2201,32 +2201,48 @@
 us.getMessage(),
+%0A               
  %22Pool status:OK
@@ -2344,17 +2344,67 @@
 ort: %22 +
- 
+%0A                        portKey);%0A        destroy(
 portKey)
@@ -2806,16 +2806,32 @@
 ssage(),
+%0A               
  %22Pool s
@@ -2944,24 +2944,50 @@
 rt: 8888%22);%0A
+        destroy(portKey);%0A
     %7D%0A%0A    p
@@ -3513,10 +3513,247 @@
 %0A    %7D%0A%0A
+    private void destroy(String portKey) %7B%0A        DataStore dataStore = ExtensionLoader.getExtensionLoader(DataStore.class).getDefaultExtension();%0A        dataStore.remove(CommonConstants.EXECUTOR_SERVICE_COMPONENT_KEY, portKey);%0A    %7D%0A
 %7D%0A

fix #8022 Optimize the ThreadPoolStatusCheckerTest test case (#8023)