package jnpf.cultivate.controller.web;

import cn.dev33.satoken.annotation.SaIgnore;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jnpf.base.ActionResult;
import jnpf.cultivate.mapper.*;
import jnpf.database.util.DataSourceUtil;
import jnpf.database.util.DynamicDataSourceUtil;
import jnpf.exception.LoginException;
import jnpf.model.cultivate.po.position.*;
import jnpf.util.NoDataSourceBind;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.jdbc.ScriptRunner;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

/**
 * 培训课程数据迁移
 *
 * @author fantaibao
 * @date 2024/01/17
 */
@RestController
@Slf4j
@RequestMapping("/migrate")
public class MigrateController {

    @Resource
    private FtbCultivatePositionCourseMapper ftbCultivatePositionCourseMapper;
    @Resource
    private FtbCultivatePositionCourseExamMapper ftbCultivatePositionCourseExamMapper;
    @Resource
    private FtbCultivatePositionCourseIdentityMapper ftbCultivatePositionCourseIdentityMapper;
    @Resource
    private FtbCultivatePositionExamIdentifyMapper ftbCultivatePositionExamIdentifyMapper;
    @Resource
    private FtbCultivatePositionExamMapper ftbCultivatePositionExamMapper;
    @Resource
    private FtbCultivatePositionMapper ftbCultivatePositionMapper;

    @Autowired
    private DataSourceUtil dataSourceUtil;


    /**
     * 课程迁移数据时更新courseId
     * 警告，非迁移数据时请勿使用，会造成所有课程规则ID更新
     *
     * @return
     * @throws LoginException
     */
    @GetMapping("/training-data-migration")
    @SaIgnore
    @Transactional
    public ActionResult course() throws LoginException {
        // 岗位学习表
        List<FtbCultivatePosition> ftbCultivatePositions = ftbCultivatePositionMapper.selectList(Wrappers.emptyWrapper());
        for (FtbCultivatePosition ftbCultivatePosition : ftbCultivatePositions) {
            // 岗位学习课程关联表
            LambdaUpdateWrapper<FtbCultivatePositionCourse> updateWrappera = Wrappers.lambdaUpdate();
            updateWrappera.set(FtbCultivatePositionCourse::getPostRankId, ftbCultivatePosition.getPostId());
            updateWrappera.eq(FtbCultivatePositionCourse::getPostLearnId, ftbCultivatePosition.getId());
            ftbCultivatePositionCourseMapper.update(null, updateWrappera);
            // 岗位学习课程关联考试表
            LambdaUpdateWrapper<FtbCultivatePositionCourseExam> updateWrapperb = Wrappers.lambdaUpdate();
            updateWrapperb.set(FtbCultivatePositionCourseExam::getPostRankId, ftbCultivatePosition.getPostId());
            updateWrapperb.eq(FtbCultivatePositionCourseExam::getPostLearnId, ftbCultivatePosition.getId());
            ftbCultivatePositionCourseExamMapper.update(null, updateWrapperb);
            // 岗位学习课程关联鉴定表
            LambdaUpdateWrapper<FtbCultivatePositionCourseIdentity> updateWrapper = Wrappers.lambdaUpdate();
            updateWrapper.set(FtbCultivatePositionCourseIdentity::getPostRankId, ftbCultivatePosition.getPostId());
            updateWrapper.eq(FtbCultivatePositionCourseIdentity::getPostLearnId, ftbCultivatePosition.getId());
            ftbCultivatePositionCourseIdentityMapper.update(null, updateWrapper);

            // 岗位学习考试关联表
            LambdaUpdateWrapper<FtbCultivatePositionExam> updateWrapperc = Wrappers.lambdaUpdate();
            updateWrapperc.set(FtbCultivatePositionExam::getPostRankId, ftbCultivatePosition.getPostId());
            updateWrapperc.eq(FtbCultivatePositionExam::getPostLearnId, ftbCultivatePosition.getId());
            ftbCultivatePositionExamMapper.update(null, updateWrapperc);
            // 岗位学习鉴定关联表
            LambdaUpdateWrapper<FtbCultivatePositionExamIdentify> updateWrapperd = Wrappers.lambdaUpdate();
            updateWrapperd.set(FtbCultivatePositionExamIdentify::getPostRankId, ftbCultivatePosition.getPostId());
            updateWrapperd.eq(FtbCultivatePositionExamIdentify::getPostLearnId, ftbCultivatePosition.getId());
            ftbCultivatePositionExamIdentifyMapper.update(null, updateWrapperd);
        }
        return ActionResult.success();
    }


    /**
     * 升级数据库
     *
     * @param dataSourceName 数据源名称
     * @return {@link ActionResult}
     */
    @SaIgnore
    @PostMapping("/upgrade/sql")
    @NoDataSourceBind
    public ActionResult upgradeDatabase(@RequestParam("dataSourceName") String dataSourceName
            , @RequestPart("file") MultipartFile file) throws SQLException {
        DataSource dataSource = DynamicDataSourceUtil.createDataSource(dataSourceUtil);
        try (InputStream inputStream = file.getInputStream()) {
            Connection dataSourceConnection = DataSourceUtils.doGetConnection(dataSource);
            dataSourceConnection.setCatalog(dataSourceName);
            var scriptRunner = new ScriptRunner(dataSourceConnection);
            scriptRunner.setSendFullScript(false);
            scriptRunner.setAutoCommit(false);
            scriptRunner.setStopOnError(true);
            try {
                scriptRunner.runScript(new InputStreamReader(inputStream));
            } finally {
                DataSourceUtils.doReleaseConnection(dataSourceConnection, dataSource);
            }
        } catch (DataAccessException e) {
            log.error("execute sql error", e);
        } catch (Exception e1) {
            log.error("failed to initialize dataSource from schema file {} ", dataSourceName, e1);
        }
        return ActionResult.success();
    }

}
