package ${basePackage}.module.system.mgr;

import ${basePackage}.frame.base.SortType;
import ${basePackage}.frame.utils.IDgenerator;
import ${basePackage}.frame.utils.Message;
import ${basePackage}.frame.base.ErrorType;
import ${basePackage}.frame.auth.Token;
import ${basePackage}.frame.utils.MapperUtil;
import ${basePackage}.frame.utils.ValidationUtil;
import ${basePackage}.module.system.ent.Res;
import ${basePackage}.module.system.ent.ResTree;
import ${basePackage}.module.system.mpr.ResMapper;
import ${basePackage}.module.system.req.ResCreateRequest;
import ${basePackage}.module.system.req.ResDeleteRequest;
import ${basePackage}.module.system.req.ResFindRequest;
import ${basePackage}.module.system.req.ResGetRequest;
import ${basePackage}.module.system.req.ResTreeRequest;
import ${basePackage}.module.system.req.ResUpdateRequest;
import ${basePackage}.module.system.rsp.ResCreateResponse;
import ${basePackage}.module.system.rsp.ResDeleteResponse;
import ${basePackage}.module.system.rsp.ResFindResponse;
import ${basePackage}.module.system.rsp.ResGetResponse;
import ${basePackage}.module.system.rsp.ResTreeResponse;
import ${basePackage}.module.system.rsp.ResUpdateResponse;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * RES - 资源
 *
 * @author wangbing
 * @version 0.0.1
 * @since 2017-01-01
 */
@Transactional
@Service
public class ResManagerImpl implements ResManager {

    @Autowired
    private ResMapper resMapper;

    /**
     * 插入
     *
     * @param request 请求对象
     * @param token   令牌
     * @return 响应
     */
    public ResCreateResponse create(ResCreateRequest request, Token token) {
        ResCreateResponse response = new ResCreateResponse();

        ValidationUtil.validate(request, response);
        if (response.hasError()) {
            return response;
        }

        ResFindRequest resFindRequest = new ResFindRequest();
        resFindRequest.setResCode(request.getResCode());
        ResFindResponse resFindResponse = this.find(resFindRequest, token);
        if (resFindResponse.hasError()) {
            response.addErrors(resFindResponse.getErrors());
            return response;
        } else if (resFindResponse.getResult().size() > 0) {
            response.addError(ErrorType.BUSINESS_ERROR, Message.INSERT_DUPLICATE);
            return response;
        }

        long id = IDgenerator.nextId();
        Res entity = MapperUtil.map(request, Res.class);
        entity.setId(id);

        long result = resMapper.insert(entity, token);
        if (1L != result) {
            response.addError(ErrorType.BUSINESS_ERROR, Message.CREATE_FAILURE);
            return response;
        }
        response.setId(id);

        return response;
    }

    /**
     * 逻辑删除
     *
     * @param request 请求对象
     * @param token   令牌
     * @return 响应
     */
    public ResDeleteResponse delete(ResDeleteRequest request, Token token) {
        ResDeleteResponse response = new ResDeleteResponse();

        ValidationUtil.validate(request, response);
        if (response.hasError()) {
            return response;
        }

        long result = resMapper.delete(request, token);
        if (1L != result) {
            response.addError(ErrorType.BUSINESS_ERROR, Message.DELETE_FAILURE);
            return response;
        }
        response.setResult(result);

        return response;
    }

    /**
     * 更新
     *
     * @param request 请求对象
     * @param token   令牌
     * @return 响应
     */
    public ResUpdateResponse update(ResUpdateRequest request, Token token) {
        ResUpdateResponse response = new ResUpdateResponse();

        ValidationUtil.validate(request, response);
        if (response.hasError()) {
            return response;
        }

        long result = resMapper.update(request, token);
        if (1L != result) {
            response.addError(ErrorType.BUSINESS_ERROR, Message.UPDATE_FAILURE);
            return response;
        }
        response.setResult(result);

        return response;
    }

    /**
     * 查询
     *
     * @param request 请求对象
     * @param token   令牌
     * @return 响应
     */
    @Transactional(readOnly = true)
    public ResFindResponse find(ResFindRequest request, Token token) {
        ResFindResponse response = new ResFindResponse();

        ValidationUtil.validate(request, response);
        if (response.hasError()) {
            return response;
        }

        if (request.getPageSize() != 0) {
            PageHelper.startPage(request.getPageNumber(), request.getPageSize());
        }
        if (StringUtil.isNotEmpty(request.getSortKey())) {
            PageHelper.orderBy(request.getSortKey() + " " + request.getSortType());
        }
        PageInfo<Res> pageInfo = new PageInfo<>(resMapper.find(request, token));

        response.setResult(pageInfo.getList());
        response.setTotalCount(pageInfo.getTotal());

        return response;
    }

    /**
     * 获得对象
     *
     * @param request 请求对象
     * @param token   令牌
     * @return 响应
     */
    @Transactional(readOnly = true)
    public ResGetResponse get(ResGetRequest request, Token token) {
        ResGetResponse response = new ResGetResponse();

        ValidationUtil.validate(request, response);
        if (response.hasError()) {
            return response;
        }

        Res po = resMapper.get(request, token);

        if (po != null) {
            response.setRes(po);
        } else {
            response.addError(ErrorType.BUSINESS_ERROR, Message.GET_FAILURE);
        }

        return response;
    }

    @Override
    public ResTreeResponse tree(ResTreeRequest request, Token token) {
        ResTreeResponse response = new ResTreeResponse();

        ValidationUtil.validate(request, response);
        if (response.hasError()) {
            return response;
        }

        ResFindRequest resourceFindRequest = new ResFindRequest();
        resourceFindRequest.setPageSize(0);
        resourceFindRequest.setValid(true);
        resourceFindRequest.setSortKey("RES_CODE");
        resourceFindRequest.setSortType(SortType.ASC);
        ResFindResponse resourceFindResponse = this.find(resourceFindRequest, token);

        if (resourceFindResponse.hasError()) {
            response.addErrors(resourceFindResponse.getErrors());
            return response;
        }

        List<ResTree> data = new ArrayList<>();
        Map<String, ResTree> allMap = new HashMap<>();
        List<Res> result = resourceFindResponse.getResult();
        while (result.size() > 0) {
            Iterator<Res> iterator = result.iterator();
            while (iterator.hasNext()) {
                Res next = iterator.next();
                ResTree tree = new ResTree();
                tree.setId(next.getId());
                tree.setResCode(next.getResCode());
                tree.setResName(next.getResName());
                tree.setResType(next.getResType());
                tree.setResValue(next.getResValue());
                tree.setValid(next.getValid());
                tree.setRowVersion(next.getRowVersion());
                tree.setLabel(next.getResName());

                allMap.put(tree.getResCode(), tree);
                iterator.remove();
                //尝试获取上级资源
                String code = next.getResCode();
                ResTree Ptree = null;
                while (code.length() > 0) {
                    code = code.substring(0, code.length() - 1);
                    Ptree = allMap.get(code);
                    if (Ptree != null) break;
                }
                if (Ptree != null) {
                    Ptree.addChild(tree);
                } else {
                    data.add(tree);
                }
            }
        }

        response.setResult(data);
        return response;
    }
}
