package cn.ibizlab.core.data.domain;

import java.util.*;

import cn.ibizlab.core.data.lite.Setting;
import cn.ibizlab.core.data.model.DSLink;
import cn.ibizlab.util.helper.DataObject;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.springframework.util.ObjectUtils;

import java.io.Serializable;
import lombok.*;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.util.StringUtils;


/**
 * [数据源] 对象
 */
@Builder
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("数据源")
public class DSSetting implements Serializable {

    /**
     * 标识
     */
    @JSONField(name = "ds_id")
    @JsonProperty("ds_id")
    @ApiModelProperty("标识")
    private String dsId;

    /**
     * 数据源名称
     */
    @JSONField(name = "ds_name")
    @JsonProperty("ds_name")
    @ApiModelProperty("数据源名称")
    private String dsName;

    /**
     * 类型
     */
    @JSONField(name = "ds_type")
    @JsonProperty("ds_type")
    @ApiModelProperty("类型")
    private String dsType;

    /**
     * 配置
     */
    @JSONField(name = "ds_cfg")
    @JsonProperty("ds_cfg")
    @ApiModelProperty("配置")
    private String dsCfg;



    @JSONField(serialize = false)
    @JsonIgnore
    private Map<String,Object> extensionparams;

    public Object get(String key)
    {
        if(extensionparams==null)
            extensionparams= Setting.getMap(dsCfg);
        return extensionparams.get(key);
    }

    public String getStringValue(String key)
    {
        return this.getStringValue(key,"");
    }

    public String getStringValue(String key,String strDefault)
    {
        return DataObject.getStringValue(get(key),strDefault);
    }

    public DSSetting set(String key, Object value)
    {
        if(value==null)
            return this;
        if(extensionparams==null)
            extensionparams=Setting.getMap(dsCfg);

        extensionparams.put(key,value);
        List<Setting> settingList=new ArrayList<>();
        for(Map.Entry<String,Object> entry:extensionparams.entrySet()) {
            if(!entry.getKey().equalsIgnoreCase("param"))
                settingList.add(new Setting().setProperty(entry.getKey()).setValue(DataObject.getStringValue(entry.getValue(), "")));
        }
        setDsCfg(JSON.toJSONString(settingList));

        return this;
    }



    @JSONField(serialize = false)
    @JsonIgnore
    private DataSourceProperty dataSourceProperty;
    @JSONField(serialize = false)
    @JsonIgnore
    public DataSourceProperty getDataSourceProperty()
    {
        if(dataSourceProperty==null)
        {
            if(!isDatabase())
                return null;
            dataSourceProperty = new DataSourceProperty().setDriverClassName(this.getDSLinkConfig().getDriverClassName()).setUrl(this.getDSLinkConfig().getUrl())
            .setUsername(this.getDSLinkConfig().getUsername()).setPassword(this.getDSLinkConfig().getPassword())
            .setSchema(this.getDSLinkConfig().getSchema());
            dataSourceProperty.getDruid().setFilters("stat,log4j2");
        }
        return dataSourceProperty;
    }

    @JSONField(serialize = false)
    @JsonIgnore
    public boolean isMongodb()
    {
       return this.getDSLinkConfig().isMongodb();
    }

    @JSONField(serialize = false)
    @JsonIgnore
    public boolean isDatabase()
    {
        return this.getDSLinkConfig().isDatabase();
    }

    @JSONField(serialize = false)
    @JsonIgnore
    public boolean isElasticSearch()
    {
        return this.getDSLinkConfig().isElasticSearch();
    }

    @JSONField(serialize = false)
    @JsonIgnore
    public boolean isCassandra()
    {
        return this.getDSLinkConfig().isCassandra();
    }


    public Set<String> getUsings()
    {
        return this.getDSLinkConfig().getUsings();
    }

    @JSONField(serialize = false)
    @JsonIgnore
    private DSLink dsLinkConfig;
    @JSONField(serialize = false)
    @JsonIgnore
    public DSLink getDSLinkConfig()
    {
        if(dsLinkConfig==null)
        {
            dsLinkConfig = new DSLink().setName(this.getDsId()).setDescription(this.getDsName()).setDriverClassName(this.getStringValue("driver-class-name"))
                    .setUrl(this.getStringValue("url",this.getStringValue("uri")))
                    .setUsername(this.getStringValue("username")).setPassword(this.getStringValue("password"))
                    .setSchema(this.getStringValue("defaultSchema",this.getStringValue("schema")));
            String strUsings=this.getStringValue("usings");
            if(!StringUtils.isEmpty(strUsings))
            {
                Set<String> usings=new LinkedHashSet<>();
                for(String using:strUsings.split(","))
                    usings.add(using);
                dsLinkConfig.setUsings(usings);
            }

        }
        return dsLinkConfig;
    }
    public DSSetting setDSLinkConfig(DSLink dsLinkConfig)
    {
        if(dsLinkConfig!=null)
        {
            this.dsLinkConfig=dsLinkConfig;
            List<Setting> settings=new ArrayList<>();
            if(!StringUtils.isEmpty(dsLinkConfig.getName()))
                this.setDsId(dsLinkConfig.getName());
            if(!StringUtils.isEmpty(dsLinkConfig.getType()))
                this.setDsType(dsLinkConfig.getType());
            if(!StringUtils.isEmpty(dsLinkConfig.getDescription()))
                this.setDsName(dsLinkConfig.getDescription());
            if(!StringUtils.isEmpty(dsLinkConfig.getDriverClassName()))
                settings.add(new Setting().setProperty("driver-class-name").setValue(dsLinkConfig.getDriverClassName()));
            if(!StringUtils.isEmpty(dsLinkConfig.getUrl()))
                settings.add(new Setting().setProperty("url").setValue(dsLinkConfig.getUrl()));
            if(!StringUtils.isEmpty(dsLinkConfig.getUsername()))
                settings.add(new Setting().setProperty("username").setValue(dsLinkConfig.getUsername()));
            if(!StringUtils.isEmpty(dsLinkConfig.getPassword()))
                settings.add(new Setting().setProperty("password").setValue(dsLinkConfig.getPassword()));
            if(!StringUtils.isEmpty(dsLinkConfig.getSchema()))
                settings.add(new Setting().setProperty("schema").setValue(dsLinkConfig.getSchema()));
            if(!ObjectUtils.isEmpty(dsLinkConfig.getUsings()))
                settings.add(new Setting().setProperty("usings").setValue(String.join(",",dsLinkConfig.getUsings())));

            setDsCfg(JSON.toJSONString(settings));
        }

        return this;
    }



}


