package cn.ibizlab.core.data.service.impl;

import cn.ibizlab.core.data.domain.DOModel;
import cn.ibizlab.core.data.dto.*;
import cn.ibizlab.core.data.model.DSLink;
import cn.ibizlab.core.data.service.IDSSettingService;
import cn.ibizlab.core.data.service.IDataService;
import cn.ibizlab.core.data.service.ModelService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.io.Serializable;
import java.util.List;

/**
 * 实体[业务实体] 无存储服务对象接口实现
 */
@Slf4j
@Primary
@Service
public  class BaseDataService implements IDataService {

    @Override
    public DOModel getDOModel(String system, String entity)
    {
        return modelService.getDOModel(system,entity);
    }

    @Autowired
    private DbDataServiceImpl dbProxyService;

    @Autowired
    private MongoDataServiceImpl mongoProxyService;

    @Autowired
    private ModelService modelService;

    @Autowired
    private IDSSettingService dsSettingService;

    public IDataService getProxyService(String datasource)
    {
        DSLink dsLink=dsSettingService.getDataSource(datasource);
        if(dsLink.isMongodb())
            return mongoProxyService;
        else if(dsLink.isElasticSearch())
            return mongoProxyService;
        else if(dsLink.isCassandra())
            return mongoProxyService;
        else
            return dbProxyService;
    }


    @Override
    public ResponseData call(DOModel model,String scope, String method, String datasource, RequestData requestBody)
    {
        if("create".equalsIgnoreCase(method))
        {
            if(create(model, scope, datasource, requestBody.getBaseData()))
                return ResponseData.ok(requestBody.getBaseData());
            else
                return ResponseData.error(1,"");
        }
        else if("update".equalsIgnoreCase(method))
        {
            if(update(model, scope, datasource, requestBody.getBaseData()))
                return ResponseData.ok(requestBody.getBaseData());
            else
                return ResponseData.error(1,"");
        }
        else if("save".equalsIgnoreCase(method))
        {
            if(save(model, scope, datasource, requestBody.getBaseData()))
                return ResponseData.ok(requestBody.getBaseData());
            else
                return ResponseData.error(1,"");
        }
        else if("remove".equalsIgnoreCase(method))
        {
            Serializable key=requestBody.getKey();
            if(ObjectUtils.isEmpty(key))
                key=model.getKeyValue(requestBody.getBaseData(),false);
            if(ObjectUtils.isEmpty(key))
                return ResponseData.error(400,"key 没有输入");
            if(remove(model, scope, datasource, key))
                return ResponseData.ok(requestBody.getBaseData());
            else
                return ResponseData.error(1,"");
        }
        else if("get".equalsIgnoreCase(method))
        {
            Serializable key=requestBody.getKey();
            if(ObjectUtils.isEmpty(key))
                key=model.getKeyValue(requestBody.getBaseData(),false);
            if(ObjectUtils.isEmpty(key))
                return ResponseData.error(400,"key 没有输入");
            BaseData data=get(model,scope,datasource,key);
            if(data!=null)
                return ResponseData.ok(data);
            else
                return ResponseData.error(404,"");
        }
        else if("checkKey".equalsIgnoreCase(method))
        {
            if(checkKey(model, scope, datasource, requestBody.getBaseData()))
                return ResponseData.ok(requestBody.getBaseData());
            else
                return ResponseData.error(1,"");
        }
        else if("getDraft".equalsIgnoreCase(method))
        {
            return ResponseData.ok(getDraft(model, scope, datasource, requestBody.getBaseData()));
        }
        else if("createBatch".equalsIgnoreCase(method))
        {
            createBatch(model, scope, datasource, requestBody.getListData());
            return ResponseData.ok(true);
        }
        else if("updateBatch".equalsIgnoreCase(method))
        {
            updateBatch(model, scope, datasource, requestBody.getListData());
            return ResponseData.ok(true);
        }
        else if("saveBatch".equalsIgnoreCase(method))
        {
            saveBatch(model, scope, datasource, requestBody.getListData());
            return ResponseData.ok(true);
        }
        return null;
    }

    @Override
    public boolean create(DOModel model, String scope, String datasource, BaseData et)
    {
        if(StringUtils.isEmpty(datasource))datasource=model.getDefaultDataSource();
        return getProxyService(datasource).create(model,scope,datasource,et);
    }

    @Override
    public void createBatch(DOModel model, String scope, String datasource, List<BaseData> list)
    {
        if(StringUtils.isEmpty(datasource))datasource=model.getDefaultDataSource();
        getProxyService(datasource).createBatch(model,scope,datasource,list);
    }

    @Override
    public boolean update(DOModel model, String scope, String datasource, BaseData et)
    {
        if(StringUtils.isEmpty(datasource))datasource=model.getDefaultDataSource();
        return getProxyService(datasource).update(model,scope,datasource,et);
    }

    @Override
    public void updateBatch(DOModel model, String scope, String datasource, List<BaseData> list)
    {
        if(StringUtils.isEmpty(datasource))datasource=model.getDefaultDataSource();
        getProxyService(datasource).updateBatch(model,scope,datasource,list);
    }

    @Override
    public boolean remove(DOModel model, String scope, String datasource, Serializable key)
    {
        if(StringUtils.isEmpty(datasource))datasource=model.getDefaultDataSource();
        return getProxyService(datasource).remove(model,scope,datasource,key);
    }

    @Override
    public void removeBatch(DOModel model, String scope, String datasource, List<Serializable> idList)
    {
        if(StringUtils.isEmpty(datasource))datasource=model.getDefaultDataSource();
        getProxyService(datasource).removeBatch(model,scope,datasource,idList);
    }

    @Override
    public boolean removeByMap(DOModel model, String scope, String datasource, BaseData et)
    {
        if(StringUtils.isEmpty(datasource))datasource=model.getDefaultDataSource();
        return getProxyService(datasource).removeByMap(model,scope,datasource,et);
    }

    @Override
    public BaseData get(DOModel model, String scope, String datasource, Serializable key)
    {
        if(StringUtils.isEmpty(datasource))datasource=model.getDefaultDataSource();
        return getProxyService(datasource).get(model,scope,datasource,key);
    }

    @Override
    public List<BaseData> getBatch(DOModel model, String scope, String datasource, List<Serializable> idList)
    {
        if(StringUtils.isEmpty(datasource))datasource=model.getDefaultDataSource();
        return getProxyService(datasource).getBatch(model,scope,datasource,idList);
    }

    @Override
    public BaseData getByMap(DOModel model, String scope, String datasource, BaseData et)
    {
        if(StringUtils.isEmpty(datasource))datasource=model.getDefaultDataSource();
        return getProxyService(datasource).getByMap(model,scope,datasource,et);
    }

    @Override
    public BaseData getDraft(DOModel model, String scope, String datasource, BaseData et)
    {
        if(StringUtils.isEmpty(datasource))datasource=model.getDefaultDataSource();
        return getProxyService(datasource).getDraft(model,scope,datasource,et);
    }

    @Override
    public boolean checkKey(DOModel model, String scope, String datasource, BaseData et)
    {
        if(StringUtils.isEmpty(datasource))datasource=model.getDefaultDataSource();
        return getProxyService(datasource).checkKey(model,scope,datasource,et);
    }

    @Override
    public boolean save(DOModel model, String scope, String datasource, BaseData et)
    {
        if(StringUtils.isEmpty(datasource))datasource=model.getDefaultDataSource();
        return getProxyService(datasource).save(model,scope,datasource,et);
    }

    @Override
    public void saveBatch(DOModel model, String scope, String datasource, List<BaseData> list)
    {
        if(StringUtils.isEmpty(datasource))datasource=model.getDefaultDataSource();
        getProxyService(datasource).saveBatch(model,scope,datasource,list);
    }

    @Override
    public List<BaseData> select(DOModel model, String scope, String datasource, BaseData et)
    {
        if(StringUtils.isEmpty(datasource))datasource=model.getDefaultDataSource();
        return getProxyService(datasource).select(model,scope,datasource,et);
    }

    @Override
    public Page<BaseData> select(DOModel model, String scope, String datasource, BaseData et, Pageable pageable)
    {
        if(StringUtils.isEmpty(datasource))datasource=model.getDefaultDataSource();
        return getProxyService(datasource).select(model,scope,datasource,et,pageable);
    }

    @Override
    public List<BaseData> query(DOModel model, String scope, String datasource, String dataQuery, FilterData context)
    {
        if(StringUtils.isEmpty(datasource))datasource=model.getDefaultDataSource();
        return getProxyService(datasource).query(model,scope,datasource,dataQuery,context);
    }

    @Override
    public Page<BaseData> query(DOModel model, String scope, String datasource, String dataQuery, FilterData context, Pageable pageable)
    {
        if(StringUtils.isEmpty(datasource))datasource=model.getDefaultDataSource();
        return getProxyService(datasource).query(model,scope,datasource,dataQuery,context,pageable);
    }

    @Override
    public List<BaseData> selectRaw(DOModel model, String scope, String datasource, String sql, FilterData context)
    {
        if(StringUtils.isEmpty(datasource))datasource=model.getDefaultDataSource();
        return getProxyService(datasource).selectRaw(model,scope,datasource,sql,context);
    }

    @Override
    public boolean execRaw(DOModel model, String scope, String datasource, String sql, BaseData param)
    {
        if(StringUtils.isEmpty(datasource))datasource=model.getDefaultDataSource();
        return getProxyService(datasource).execRaw(model,scope,datasource,sql,param);
    }

    @Override
    public List<BaseData> fetch(DOModel model, String scope, String datasource, String dataSet, FilterData context)
    {
        if(StringUtils.isEmpty(datasource))datasource=model.getDefaultDataSource();
        return getProxyService(datasource).fetch(model,scope,datasource,dataSet,context);
    }

    @Override
    public Page<BaseData> fetch(DOModel model, String scope, String datasource, String dataSet, FilterData context, Pageable pageable)
    {
        if(StringUtils.isEmpty(datasource))datasource=model.getDefaultDataSource();
        return getProxyService(datasource).fetch(model,scope,datasource,dataSet,context,pageable);
    }


}


