package cn.reghao.bnt.web.devops.build.service.impl;

import cn.reghao.bnt.common.machine.Disk;
import cn.reghao.bnt.common.machine.Machine;
import cn.reghao.bnt.web.devops.build.model.po.BuildDir;
import cn.reghao.bnt.web.devops.build.service.BuildDirService;
import cn.reghao.bnt.web.devops.builder.model.LocalBuildDir;
import cn.reghao.jutil.jdk.converter.ByteConverter;
import cn.reghao.jutil.jdk.machine.data.detail.DiskDetail;
import cn.reghao.jutil.jdk.web.result.Result;
import cn.reghao.jutil.jdk.web.result.ResultStatus;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;

/**
 * @author reghao
 * @date 2021-09-17 15:56:49
 */
@Slf4j
@Service
public class BuildDirServiceImpl implements BuildDirService {
    // TODO 将 machineId 设置为一个常量
    private static BuildDir buildDir;
    private static DiskDetail diskDetail;
    private final ByteConverter byteConverter;
    private final Disk disk;

    public BuildDirServiceImpl(Disk disk, ByteConverter byteConverter) {
        this.disk = disk;
        this.byteConverter = byteConverter;
    }

    @Override
    public void init(String dirPath) throws Exception {
        buildDir = createLocalBuildDir(dirPath);
    }

    private BuildDir createLocalBuildDir(String localBuildDir) throws Exception {
        diskDetail = disk.diskDetail(localBuildDir);
        String machineId = Machine.ID;
        String machineIpv4 = Machine.IPV4;
        String mountedOn = diskDetail.getMountedOn();
        long total = diskDetail.getTotal();
        String totalStr = byteConverter.convert(total);
        long used = diskDetail.getUsed();
        String usedStr = byteConverter.convert(used);
        long avail = diskDetail.getAvail();
        String availStr = byteConverter.convert(avail);

        BuildDir buildDir = new BuildDir(machineId, machineIpv4, localBuildDir, mountedOn,
                total, totalStr, used, usedStr, avail, availStr);
        createLocalBuildDir(buildDir);
        return buildDir;
    }

    private void createLocalBuildDir(BuildDir buildDir) throws Exception {
        setLocalBuildDir(buildDir);
        File localRepo = new File(LocalBuildDir.localRepo);
        if (!localRepo.exists() && !localRepo.mkdirs()) {
            throw new Exception(localRepo.getAbsolutePath() + " 不存在且创建失败");
        }

        File compileDir = new File(LocalBuildDir.compileDir);
        if (!compileDir.exists() && !compileDir.mkdirs()) {
            throw new Exception(compileDir.getAbsolutePath() + " 不存在且创建失败");
        }

        File packDir = new File(LocalBuildDir.packDir);
        if (!packDir.exists() && !packDir.mkdirs()) {
            throw new Exception(packDir.getAbsolutePath() + " 不存在且创建失败");
        }
    }

    private void setLocalBuildDir(BuildDir buildDir) {
        String dirPath = buildDir.getDirPath();
        LocalBuildDir.localRepo = String.format("%s/local-repo", dirPath);
        LocalBuildDir.compileDir = String.format("%s/compile-dir", dirPath);
        LocalBuildDir.packDir = String.format("%s/pack-dir", dirPath);
    }

    @Override
    public synchronized Result erase() {
        // TODO 保证没有 app 处在构建状态
        String localRepo = LocalBuildDir.localRepo;
        erase(localRepo);
        String compileDir = LocalBuildDir.compileDir;
        erase(compileDir);
        String packDir = LocalBuildDir.packDir;
        erase(packDir);
        return Result.result(ResultStatus.SUCCESS);
    }

    private void erase(String dirPath) {
        try {
            File dir = new File(dirPath);
            FileUtils.cleanDirectory(dir);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public BuildDir get() {
        buildDir.setUsed(diskDetail.getUsed());
        buildDir.setAvail(diskDetail.getAvail());
        buildDir.setUsedStr(byteConverter.convert(diskDetail.getUsed()));
        buildDir.setAvailStr(byteConverter.convert(diskDetail.getAvail()));
        return buildDir;
    }
}
