package com.keyware.shandan.bianmu.utils;

import com.keyware.shandan.bianmu.entity.DirectoryVo;
import com.keyware.shandan.bianmu.entity.MetadataBasicVo;
import com.keyware.shandan.bianmu.enums.DirectoryType;
import com.keyware.shandan.bianmu.enums.ReviewStatus;
import com.keyware.shandan.bianmu.service.DirectoryService;
import com.keyware.shandan.bianmu.service.MetadataService;
import com.keyware.shandan.common.util.StringUtils;
import com.keyware.shandan.system.entity.SysFile;
import com.keyware.shandan.system.service.SysFileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.validation.constraints.NotNull;

@Slf4j
@Component
public class DirectoryBuilder {

    @Autowired
    private DirectoryService directoryService;

    @Autowired
    private MetadataService metadataService;

    @Autowired
    private SysFileService fileService;

    /**
     * 生成一个数据表类型的目录
     *
     * @param parentDirId 父级目录ID
     * @param metaId      数据表ID
     * @return 目录
     */
    public DirectoryVo buildMetadataDir(@NotNull String parentDirId, @NotNull String metaId) {
        DirectoryVo parent = directoryService.getById(parentDirId);
        MetadataBasicVo metadata = metadataService.getById(metaId);
        String dirName = StringUtils.hasTextByDefault(metadata.getMetadataComment(), metadata.getMetadataName());

        return extendsParentBuilder(parent)
                .resourceId(metaId)
                .directoryType(DirectoryType.METADATA)
                .directoryName(dirName)
                .directoryPath(parent.getDirectoryPath() + "/" + dirName)
                .reviewStatus(ReviewStatus.PASS)
                .build();
    }

    /**
     * 生成一个文件类型的目录
     *
     * @param parentDirId 父级目录ID
     * @param fileId      文件ID
     * @return 目录
     */
    public DirectoryVo buildFileDir(@NotNull String parentDirId, @NotNull String fileId) {
        SysFile file = fileService.getById(fileId);
        return buildFileDir(parentDirId, file);
    }

    /**
     * 生成一个文件类型的目录
     *
     * @param parentDirId 父级目录ID
     * @param file        文件
     * @return 目录
     */
    public DirectoryVo buildFileDir(@NotNull String parentDirId, @NotNull SysFile file) {
        DirectoryVo parent = directoryService.getById(parentDirId);

        return extendsParentBuilder(parent)
                .resourceId(file.getId())
                .directoryType(DirectoryType.FILE)
                .directoryName(file.getFileName())
                .directoryPath(parent.getDirectoryPath() + "/" + file.getFileName())
                .reviewStatus(ReviewStatus.PASS)
                .build();
    }

    /**
     * 生成一个数据表软件连接类型的目录
     *
     * @param parentDirId 父级目录ID
     * @param sourceId    数据表资源ID
     * @return 目录
     */
    public DirectoryVo buildMetadataLinkDir(@NotNull String parentDirId, @NotNull String sourceId) {
        DirectoryVo directory = buildMetadataDir(parentDirId, sourceId);
        directory.setDirectoryType(DirectoryType.LINK_METADATA);
        return directory;
    }

    /**
     * 生成一个文件软件连接类型的目录
     *
     * @param parentDirId 父级目录ID
     * @param sourceId    文件ID
     * @return 目录
     */
    public DirectoryVo buildFileLinkDir(@NotNull String parentDirId, @NotNull String sourceId) {
        DirectoryVo directory = buildFileDir(parentDirId, sourceId);
        directory.setDirectoryType(DirectoryType.LINK_FILE);
        return directory;
    }

    /**
     * 生成一个软链接目录
     *
     * @param parentDirId 链接的父级目录ID
     * @param sourceId    链接的源目录ID
     * @return 目录
     */
    public DirectoryVo buildLinkDir(@NotNull String parentDirId, @NotNull String sourceId) {
        DirectoryVo targetDir = directoryService.getById(parentDirId);
        DirectoryVo sourceDir = directoryService.getById(sourceId);

        return extendsParentBuilder(targetDir)
                .resourceId(sourceId)
                .directoryType(DirectoryType.LINK_DIR)
                .directoryName(sourceDir.getDirectoryName())
                .directoryPath(targetDir.getDirectoryPath() + "/" + sourceDir.getDirectoryName())
                .build();
    }

    public static DirectoryVo buildByParent(DirectoryVo parent){
        return extendsParentBuilder(parent).build();
    }

    /**
     * 基于继承父级目录权限相关设置的目录构建器
     *
     * @param parent 父级目录
     * @return 目录构建器
     */
    private static DirectoryVo.DirectoryVoBuilder extendsParentBuilder(DirectoryVo parent) {
        return DirectoryVo.builder()
                .parentId(parent.getId())
                // 默认继承父级目录类型
                .directoryType(parent.getDirectoryType())
                // 继承目录归属者设置
                .owner(parent.getOwner())
                .ownerId(parent.getOwnerId())
                .ownerType(parent.getOwnerType())
                // 继承权限设置
                .permisAllParent(parent.getPermisAllParent())
                .permisParent(parent.getPermisParent())
                .permisAllChild(parent.getPermisAllChild())
                .permisChild(parent.getPermisChild())
                .permisEveryone(parent.getPermisEveryone())
                // 设置审核状态
                .reviewStatus(ReviewStatus.UN_SUBMIT);
    }
}
