/*
 * Decompiled with CFR 0.152.
 */
package org.apache.logging.log4j.spi;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.apache.logging.log4j.spi.ThreadContextMap;
import org.apache.logging.log4j.util.PropertiesUtil;

public class DefaultThreadContextMap
implements ThreadContextMap {
    public static final String INHERITABLE_MAP = "isThreadContextMapInheritable";
    private final boolean useMap;
    private final ThreadLocal<Map<String, String>> localMap;

    public DefaultThreadContextMap(boolean useMap) {
        this.useMap = useMap;
        this.localMap = DefaultThreadContextMap.createThreadLocalMap(useMap);
    }

    static ThreadLocal<Map<String, String>> createThreadLocalMap(final boolean isMapEnabled) {
        PropertiesUtil managerProps = PropertiesUtil.getProperties();
        boolean inheritable = managerProps.getBooleanProperty(INHERITABLE_MAP);
        if (inheritable) {
            return new InheritableThreadLocal<Map<String, String>>(){

                @Override
                protected Map<String, String> childValue(Map<String, String> parentValue) {
                    return parentValue != null && isMapEnabled ? Collections.unmodifiableMap(new HashMap<String, String>(parentValue)) : null;
                }
            };
        }
        return new ThreadLocal<Map<String, String>>();
    }

    @Override
    public void put(String key, String value) {
        if (!this.useMap) {
            return;
        }
        Map<String, String> map = this.localMap.get();
        map = map == null ? new HashMap<String, String>() : new HashMap<String, String>(map);
        map.put(key, value);
        this.localMap.set(Collections.unmodifiableMap(map));
    }

    @Override
    public String get(String key) {
        Map<String, String> map = this.localMap.get();
        return map == null ? null : map.get(key);
    }

    @Override
    public void remove(String key) {
        Map<String, String> map = this.localMap.get();
        if (map != null) {
            HashMap<String, String> copy = new HashMap<String, String>(map);
            copy.remove(key);
            this.localMap.set(Collections.unmodifiableMap(copy));
        }
    }

    @Override
    public void clear() {
        this.localMap.remove();
    }

    @Override
    public boolean containsKey(String key) {
        Map<String, String> map = this.localMap.get();
        return map != null && map.containsKey(key);
    }

    @Override
    public Map<String, String> getCopy() {
        Map<String, String> map = this.localMap.get();
        return map == null ? new HashMap<String, String>() : new HashMap<String, String>(map);
    }

    @Override
    public Map<String, String> getImmutableMapOrNull() {
        return this.localMap.get();
    }

    @Override
    public boolean isEmpty() {
        Map<String, String> map = this.localMap.get();
        return map == null || map.size() == 0;
    }

    public String toString() {
        Map<String, String> map = this.localMap.get();
        return map == null ? "{}" : map.toString();
    }

    public int hashCode() {
        int prime = 31;
        int result = 1;
        Map<String, String> map = this.localMap.get();
        result = 31 * result + (map == null ? 0 : ((Object)map).hashCode());
        result = 31 * result + (this.useMap ? 1231 : 1237);
        return result;
    }

    public boolean equals(Object obj) {
        ThreadContextMap other;
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (obj instanceof DefaultThreadContextMap) {
            other = (DefaultThreadContextMap)obj;
            if (this.useMap != ((DefaultThreadContextMap)other).useMap) {
                return false;
            }
        }
        if (!(obj instanceof ThreadContextMap)) {
            return false;
        }
        other = (ThreadContextMap)obj;
        Map<String, String> map = this.localMap.get();
        Map<String, String> otherMap = other.getImmutableMapOrNull();
        return !(map == null ? otherMap != null : !((Object)map).equals(otherMap));
    }
}
