/*
 * 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.common.config;

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

import java.lang.reflect.Field;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * The type Environment configuration test.
 */
public class EnvironmentConfigurationTest {

    private static final String MOCK_KEY = "DUBBO_KEY";
    private static final String MOCK_VALUE = "mockValue";

    /**
     * Init.
     */
    @BeforeEach
    public void init() {

    }

    @Test
    public void testGetInternalProperty() {
        Map<String, String> map = new HashMap<>();
        map.put(MOCK_KEY, MOCK_VALUE);
        try {
            setEnv(map);
            EnvironmentConfiguration configuration = new EnvironmentConfiguration();
            // this UT maybe only works on particular platform, assert only when value is not null.
            Assertions.assertEquals(MOCK_VALUE, configuration.getInternalProperty("dubbo.key"));
            Assertions.assertEquals(MOCK_VALUE, configuration.getInternalProperty("key"));
            Assertions.assertEquals(MOCK_VALUE, configuration.getInternalProperty("dubbo_key"));
            Assertions.assertEquals(MOCK_VALUE, configuration.getInternalProperty(MOCK_KEY));
        } catch (Exception e) {
            // skip test.
            e.printStackTrace();
        }
    }

    protected static void setEnv(Map<String, String> newenv) throws Exception {
        try {
            Class<?> processEnvironmentClass = Class.forName("java.lang.ProcessEnvironment");
            Field theEnvironmentField = processEnvironmentClass.getDeclaredField("theEnvironment");
            theEnvironmentField.setAccessible(true);
            Map<String, String> env = (Map<String, String>) theEnvironmentField.get(null);
            env.putAll(newenv);
            Field theCaseInsensitiveEnvironmentField = processEnvironmentClass.getDeclaredField("theCaseInsensitiveEnvironment");
            theCaseInsensitiveEnvironmentField.setAccessible(true);
            Map<String, String> cienv = (Map<String, String>) theCaseInsensitiveEnvironmentField.get(null);
            cienv.putAll(newenv);
        } catch (NoSuchFieldException e) {
            Class[] classes = Collections.class.getDeclaredClasses();
            Map<String, String> env = System.getenv();
            for (Class cl : classes) {
                if ("java.util.Collections$UnmodifiableMap".equals(cl.getName())) {
                    Field field = cl.getDeclaredField("m");
                    field.setAccessible(true);
                    Object obj = field.get(env);
                    Map<String, String> map = (Map<String, String>) obj;
                    map.clear();
                    map.putAll(newenv);
                }
            }
        }
    }

    private static void updateEnv(String name, String val) throws ReflectiveOperationException {
        Map<String, String> env = System.getenv();
        Field field = env.getClass().getDeclaredField("m");
        field.setAccessible(true);
        ((Map<String, String>) field.get(env)).put(name, val);
    }
    /**
     * Clean.
     */
    @AfterEach
    public void clean(){

    }

}
