package com.bcxin.Infrastructures;

import com.bcxin.Infrastructures.exceptions.BadTenantException;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

public class TenantContext {
    private TenantContext() {

    }

    private void init(){

    }

    private static volatile TenantContext _tenantContext;
    public static TenantContext getInstance() {
        if (_tenantContext == null) {
            synchronized (TenantContext.class) {
                if (_tenantContext == null) {
                    _tenantContext = new TenantContext();
                    _tenantContext.init();
                }
            }
        }

        return _tenantContext;
    }

    private InjectResolver injectResolver;
    public void setInjectResolver(InjectResolver injectResolver) {
        this.injectResolver = injectResolver;
    }

    public <T> T resolve(Class<T> tClass) {
        if (injectResolver == null) {
            throw new BadTenantException("InjectResolverFactory未正确初始化");
        }

        return injectResolver.resolve(tClass);
    }

    public <T> Collection<T> resolveAll(Class<T> tClass) {
        if (injectResolver == null) {
            throw new BadTenantException("InjectResolverFactory未正确初始化");
        }

        return injectResolver.resolveAll(tClass);
    }

    private static final ThreadLocal<Map<Object, Object>> attachmentsContainer = new ThreadLocal<>();
    public void setValue(Object key, Object value) {
        Map<Object, Object> attachments = attachmentsContainer.get();

        if (attachments == null) {
            attachments = new HashMap<>();
        }

        if(value==null)
        {
            attachments.remove(key);
        }else {
            attachments.put(key, value);
        }
        attachmentsContainer.set(attachments);
    }

    public <T> T getValueAndRemove(Object key) {
        Map<Object, Object> attachments = attachmentsContainer.get();
        if (attachments == null) {
            return null;
        }

        T data = (T) attachments.get(key);
        this.setValue(key, null);

        return data;
    }


    private static final TenantUserContext userContext = new TenantUserContext();
    public TenantUserContext getUserContext() {
        return userContext;
    }
}
