package com.xmomen.module.resource.service.impl;

import com.xmomen.module.resource.api.DfsPath;
import com.xmomen.module.resource.api.DfsSdk;
import com.xmomen.module.resource.api.DfsService;
import com.xmomen.module.resource.entity.Resource;
import com.xmomen.module.resource.entity.ResourceExample;
import com.xmomen.module.resource.mapper.ResourceMapperExt;
import com.xmomen.module.resource.model.ResourceCreate;
import com.xmomen.module.resource.model.ResourceQuery;
import com.xmomen.module.resource.model.ResourceUpdate;
import com.xmomen.module.resource.model.ResourceModel;
import com.xmomen.module.resource.service.ResourceService;
import com.xmomen.framework.mybatis.dao.MybatisDao;
import com.xmomen.framework.mybatis.page.Page;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.exceptions.TooManyResultsException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 资源服务接口的实现类，负责处理资源的增删改查等业务逻辑。
 *
 * @author tanxinzheng
 * @version 1.0.0
 * @date 2017-4-10 23:26:20
 */
@Service
public class ResourceServiceImpl implements ResourceService {

    // 注入 Mybatis 数据访问对象，用于执行数据库操作
    @Autowired
    MybatisDao mybatisDao;

    /**
     * 新增资源目录，使用事务管理。
     *
     * @param resourceModel 新增资源目录对象参数
     * @return 资源目录领域对象，如果创建成功返回对应的 ResourceModel，否则返回 null
     */
    @Override
    @Transactional
    public ResourceModel createResource(ResourceModel resourceModel) {
        // 调用 createResource 方法创建资源实体
        Resource resource = createResource(resourceModel.getEntity());
        if (resource != null) {
            // 根据创建的资源实体的 ID 获取对应的资源模型对象
            return getOneResourceModel(resource.getId());
        }
        return null;
    }

    /**
     * 新增资源目录实体对象，使用事务管理。
     *
     * @param resource 新增资源目录实体对象参数
     * @return 资源目录实体对象
     */
    @Override
    @Transactional
    public Resource createResource(Resource resource) {
        // 使用 MybatisDao 插入资源实体到数据库
        return mybatisDao.insertByModel(resource);
    }

    /**
     * 批量新增资源目录，使用事务管理。
     *
     * @param resourceModels 新增资源目录对象集合参数
     * @return 资源目录领域对象集合
     */
    @Override
    @Transactional
    public List<ResourceModel> createResources(List<ResourceModel> resourceModels) {
        List<ResourceModel> resourceModelList = null;
        for (ResourceModel resourceModel : resourceModels) {
            // 逐个创建资源模型对象
            resourceModel = createResource(resourceModel);
            if (resourceModel != null) {
                if (resourceModelList == null) {
                    resourceModelList = new ArrayList<>();
                }
                // 将创建成功的资源模型对象添加到集合中
                resourceModelList.add(resourceModel);
            }
        }
        return resourceModelList;
    }

    /**
     * 更新资源目录，使用事务管理。
     *
     * @param resourceModel 更新资源目录对象参数
     */
    @Override
    @Transactional
    public void updateResource(ResourceModel resourceModel) {
        // 将资源模型对象转换为实体对象并使用 MybatisDao 更新到数据库
        mybatisDao.update(resourceModel.getEntity());
    }

    /**
     * 更新资源目录实体对象，使用事务管理。
     *
     * @param resource 新增资源目录实体对象参数
     */
    @Override
    @Transactional
    public void updateResource(Resource resource) {
        // 使用 MybatisDao 更新资源实体到数据库
        mybatisDao.update(resource);
    }

    /**
     * 删除资源目录，使用事务管理，根据主键数组删除。
     *
     * @param ids 主键数组
     */
    @Override
    @Transactional
    public void deleteResource(String[] ids) {
        ResourceExample resourceExample = new ResourceExample();
        // 创建查询条件，设置 ID 在指定数组中
        resourceExample.createCriteria().andIdIn(Arrays.<String>asList((String[]) ids));
        // 使用 MybatisDao 根据查询条件删除资源
        mybatisDao.deleteByExample(resourceExample);
    }

    /**
     * 删除资源目录，使用事务管理，根据单个主键删除。
     *
     * @param id 主键
     */
    @Override
    @Transactional
    public void deleteResource(String id) {
        // 使用 MybatisDao 根据主键删除资源
        mybatisDao.deleteByPrimaryKey(Resource.class, id);
    }

    /**
     * 查询资源目录领域分页对象（带参数条件）。
     *
     * @param limit         每页最大数
     * @param offset        页码
     * @param resourceQuery 查询参数
     * @return 资源目录参数对象的分页对象
     */
    @Override
    public Page<ResourceModel> getResourceModelPage(int limit, int offset, ResourceQuery resourceQuery) {
        // 使用 MybatisDao 进行分页查询，指定查询语句的命名空间和参数
        return (Page<ResourceModel>) mybatisDao.selectPage(ResourceMapperExt.ResourceMapperNameSpace + "getResourceModel", resourceQuery, limit, offset);
    }

    /**
     * 查询资源目录领域分页对象（无参数条件）。
     *
     * @param limit  每页最大数
     * @param offset 页码
     * @return 资源目录领域对象的分页对象
     */
    @Override
    public Page<ResourceModel> getResourceModelPage(int limit, int offset) {
        // 使用 MybatisDao 进行分页查询，不传递查询参数
        return (Page<ResourceModel>) mybatisDao.selectPage(ResourceMapperExt.ResourceMapperNameSpace + "getResourceModel", null, limit, offset);
    }

    /**
     * 查询资源目录领域集合对象（带参数条件）。
     *
     * @param resourceQuery 查询参数对象
     * @return 资源目录领域集合对象
     */
    @Override
    public List<ResourceModel> getResourceModelList(ResourceQuery resourceQuery) {
        // 使用 MyBatis 的 SqlSessionTemplate 进行查询，指定查询语句的命名空间和参数
        return mybatisDao.getSqlSessionTemplate().selectList(ResourceMapperExt.ResourceMapperNameSpace + "getResourceModel", resourceQuery);
    }

    /**
     * 查询资源目录领域集合对象（无参数条件）。
     *
     * @return 资源目录领域集合对象
     */
    @Override
    public List<ResourceModel> getResourceModelList() {
        // 使用 MyBatis 的 SqlSessionTemplate 进行查询，不传递查询参数
        return mybatisDao.getSqlSessionTemplate().selectList(ResourceMapperExt.ResourceMapperNameSpace + "getResourceModel");
    }

    /**
     * 查询资源目录实体对象。
     *
     * @param id 主键
     * @return 资源目录实体对象
     */
    @Override
    public Resource getOneResource(String id) {
        // 使用 MybatisDao 根据主键查询资源实体
        return mybatisDao.selectByPrimaryKey(Resource.class, id);
    }

    /**
     * 根据主键查询单个对象。
     *
     * @param id 主键
     * @return 资源目录领域对象
     */
    @Override
    public ResourceModel getOneResourceModel(String id) {
        ResourceQuery resourceQuery = new ResourceQuery();
        // 设置查询条件为主键
        resourceQuery.setId(id);
        // 使用 MyBatis 的 SqlSessionTemplate 进行查询，指定查询语句的命名空间和参数
        return mybatisDao.getSqlSessionTemplate().selectOne(ResourceMapperExt.ResourceMapperNameSpace + "getResourceModel", resourceQuery);
    }

    /**
     * 根据查询参数查询单个对象（此方法只用于提供精确查询单个对象，若结果数超过 1，则会报错）。
     *
     * @param resourceQuery 资源目录查询参数对象
     * @return 资源目录领域对象
     * @throws TooManyResultsException 如果查询结果超过一个，抛出此异常
     */
    @Override
    public ResourceModel getOneResourceModel(ResourceQuery resourceQuery) throws TooManyResultsException {
        // 使用 MyBatis 的 SqlSessionTemplate 进行查询，指定查询语句的命名空间和参数
        return mybatisDao.getSqlSessionTemplate().selectOne(ResourceMapperExt.ResourceMapperNameSpace + "getResourceModel", resourceQuery);
    }
}