package com.nokia.sms.task;

import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.SftpException;
import com.nokia.common.ssh.SSHUtil;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import de.siegmar.fastcsv.reader.CsvReader;
import de.siegmar.fastcsv.reader.CsvRow;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

@Component
@Slf4j
public class SyncTask {
    @Value("${sms.blk.ssh.host:10.17.182.24}")
    private String host;
    @Value("${sms.blk.ssh.port:22}")
    private Integer port;
    @Value("${sms.blk.ssh.username:sassftp}")
    private String username;
    @Value("${sms.blk.ssh.password:Flzx3qc!}")
    private String password;
    @Value("${sms.blk.ssh.sourceDir:files/black_list/}")
    private String sourceDir;
    @Value("${sms.blk.ssh.targetDir:download/}")
    private String downloadTargetDir;

    private final JdbcTemplate jdbcTemplate;

    public SyncTask(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @XxlJob("smsBlackListSync")
    public void smsBlackListSync() {
        try {
            // 创建文件夹
            Files.createDirectories(Paths.get(downloadTargetDir));
            SSHUtil sshUtil = new SSHUtil(host, port, username, password);
            // 获取文件列表
            List<String> list = sshUtil.ls(sourceDir);
            if (CollectionUtils.isEmpty(list)) {
                log.info("没有文件");
                XxlJobHelper.log("没有文件");
                return;
            }

            log.info("扫描到的文件: {}", list);
            XxlJobHelper.log("扫描到的文件: {}", list);
            for (String t : list) {
                // 跳过临时文件
                if (t.endsWith(".tmp")) {
                    continue;
                }

                // 删除空文件
                if (t.endsWith("_0")) {
                    log.info("删除空文件: {}", t);
                    XxlJobHelper.log("删除空文件: {}", t);
                    sshUtil.rm(sourceDir + t);
                    continue;
                }
                singleTask(t);
            }
        } catch (Exception e) {
            log.error("发生异常了: {}", e.getMessage(), e);
            XxlJobHelper.log("发生异常了: {}", e.getMessage(), e);
            XxlJobHelper.handleFail(e.getMessage());
        }
    }

    /**
     * 单一任务
     *
     * @param filename 文件名
     */
    public void singleTask(String filename) throws JSchException, IOException, SftpException {
        download(filename);
        importData(filename);
    }

    /**
     * 下载文件
     *
     * @param filename 文件名
     */
    public void download(String filename) throws JSchException, IOException, SftpException {
        log.info("下载文件: {}", filename);
        XxlJobHelper.log("下载文件: {}", filename);
        SSHUtil sshUtil = new SSHUtil(host, port, username, password);
        String src = sourceDir + filename;
        String dst = downloadTargetDir + filename;
        sshUtil.get(src, dst);
        // 删除远程文件
        log.info("删除远程文件: {}", filename);
        XxlJobHelper.log("删除远程文件: {}", filename);
        sshUtil.rm(src);
    }

    /**
     * 导入数据
     *
     * @param filename 文件名
     * @throws IOException ioexception
     */
    public void importData(String filename) throws IOException {
        List<Object[]> l1 = new ArrayList<>();
        List<Object[]> l2 = new ArrayList<>();
        log.info("导入: {}", filename);
        XxlJobHelper.log("导入: {}", filename);
        Path path = Paths.get(downloadTargetDir + filename);
        try (CsvReader csvReader = CsvReader.builder().build(path, StandardCharsets.UTF_8)) {
            for (CsvRow row : csvReader) {
                Object[] o1 = new Object[]{
                        row.getField(0),
                        Integer.valueOf(row.getField(1)),
                        row.getField(2),
                        row.getField(3),
                        row.getField(4),
                        Integer.valueOf(row.getField(5)),
                        Integer.valueOf(row.getField(6)),
                };
                l1.add(o1);
                Object[] o2 = new Object[]{
                        row.getField(0),
                        Integer.valueOf(row.getField(1)),
                        row.getField(2),
                        row.getField(3),
                        row.getField(4),
                        Integer.valueOf(row.getField(5)),
                        Integer.valueOf(row.getField(6)),
                        filename
                };
                l2.add(o2);
            }
        }
        String sql = "insert into sms_blk.blacklist " +
                "(phone, reason, start_time, end_time, hit_desc, operation_type, suggestion) " +
                "values (?, ?, ?, ?, ?, ?, ?) " +
                "on conflict (phone) " +
                "do update set (reason, start_time, end_time, hit_desc, operation_type, suggestion) = " +
                "(excluded.reason, excluded.start_time, excluded.end_time, excluded.hit_desc, " +
                "excluded.operation_type, excluded.suggestion)";
        jdbcTemplate.batchUpdate(sql, l1);
        sql = "insert into sms_blk.blacklist_file " +
                "(phone, reason, start_time, end_time, hit_desc, operation_type, suggestion, filename) " +
                "values (?, ?, ?, ?, ?, ?, ?, ?)";
        jdbcTemplate.batchUpdate(sql, l2);
        // todo: 删除本地文件
//        Files.deleteIfExists(path);
//        log.info("删除本地文件: {}", filename);
    }
}
