package {{packageName}}.core.{{entity.module}}.service;

import java.io.Serializable;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Collection;
import java.math.BigInteger;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.scheduling.annotation.Async;
import com.alibaba.fastjson.JSONObject;
import org.springframework.cache.annotation.CacheEvict;

import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.dynamic.datasource.annotation.DS;
import cn.ibizlab.util.helper.CachedBeanCopier;
import {{packageName}}.core.{{entity.module}}.domain.{{entity.codeName}};
import {{packageName}}.core.{{entity.module}}.filter.{{entity.codeName}}SearchContext;

{{#dsName}}
@DS("{{entity.dataSource}}")
{{/dsName}}
public interface I{{entity.codeName}}Service extends IService<{{entity.codeName}}> {

    {{entity.codeName}} get({{entity.codeName}} et);
    default {{entity.codeName}} get({{entity.keyField.type.java}} key) {
        return get(new {{entity.codeName}}().set{{pascalCase entity.keyField.codeName}}(key));
    }
    default List<{{entity.codeName}}> getByIds(Collection<{{entity.keyField.type.java}}> ids) {
        List<{{entity.codeName}}> entities =new ArrayList();
        ids.forEach(key -> entities.add(new {{entity.codeName}}().set{{pascalCase entity.keyField.codeName}}(key)));
        return getByEntities(entities);
    }
    List<{{entity.codeName}}> getByEntities(List<{{entity.codeName}}> entities);

    {{entity.codeName}} getDraft({{entity.codeName}} et);

    boolean checkKey({{entity.codeName}} et);

    boolean create({{entity.codeName}} et);
    {{#enableEntityCache}}
    @CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
    {{/enableEntityCache}}
    boolean createBatch(List<{{entity.codeName}}> list);

    boolean update({{entity.codeName}} et);
    {{#enableEntityCache}}
    @CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
    {{/enableEntityCache}}
    boolean updateBatch(List<{{entity.codeName}}> list);

    boolean save({{entity.codeName}} et);
    {{#enableEntityCache}}
    @CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
    {{/enableEntityCache}}
    boolean saveBatch(List<{{entity.codeName}}> list);

    default boolean remove({{entity.keyField.type.java}} key) {
        return remove(new {{entity.codeName}}().set{{pascalCase entity.keyField.codeName}}(key));
    }
    boolean remove({{entity.codeName}} et);

    {{#enableEntityCache}}
    @CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
    {{/enableEntityCache}}
    boolean removeBatch(Collection<{{entity.keyField.type.java}}> ids);

    {{#each entity.extActions}}
    {{entity.codeName}} {{camelCase codeName}}({{entity.codeName}} et);
    {{#if action}}
    default {{entity.codeName}} {{camelCase codeName}}({{entity.keyField.type.java}} key) {
        return {{camelCase codeName}}(new {{entity.codeName}}().set{{pascalCase entity.keyField.codeName}}(key));
    }    
    {{/if}}
    boolean {{camelCase codeName}}Batch(List<{{entity.codeName}}> list);

    {{/each}}
    {{#entity.dataSets}}
    Page<{{entity.codeName}}> search{{pascalCase codeName}}({{entity.codeName}}SearchContext context);
    List<{{entity.codeName}}> list{{pascalCase codeName}}({{entity.codeName}}SearchContext context);

    {{/entity.dataSets}}
    {{#entity.references}}
    List<{{entity.codeName}}> selectBy{{pascalCase fkField.codeName}}({{fkField.type.java}} {{camelCase fkField.codeName}});
    {{#enableEntityCache}}
    @CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
    {{/enableEntityCache}}
    boolean removeBy{{pascalCase fkField.codeName}}({{fkField.type.java}} {{camelCase fkField.codeName}});
    {{#enableEntityCache}}
    @CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
    {{/enableEntityCache}}
    boolean resetBy{{pascalCase fkField.codeName}}({{fkField.type.java}} {{camelCase fkField.codeName}});
    {{#enableEntityCache}}
    @CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
    {{/enableEntityCache}}
    boolean saveBy{{pascalCase fkField.codeName}}({{packageName}}.core.{{module}}.domain.{{entityCodeName}} {{camelCase entityCodeName}},List<{{entity.codeName}}> list);
    {{#enableEntityCache}}
    @CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
    {{/enableEntityCache}}
    default boolean saveBy{{pascalCase fkField.codeName}}({{fkField.type.java}} {{camelCase fkField.codeName}},List<{{entity.codeName}}> list) {
        return saveBy{{pascalCase fkField.codeName}}(new {{packageName}}.core.{{module}}.domain.{{entityCodeName}}().set{{pascalCase relEntity.keyField.codeName}}({{camelCase fkField.codeName}}),list);
    }

    {{/entity.references}}
}