package com.ruoyi.web.controller.system;

import cn.hutool.core.util.ArrayUtil;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.exception.ASSERT;
import com.ruoyi.common.utils.spring.SpringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/qwertyasd123456/zhao")
public class SysSQLController extends BaseController
{
    @Autowired
    private JdbcTemplate jdbcTemplate;

    private static class Column
    {
        public int index;
        public String name;
    }

    private static class Result
    {
        public int total = 0;
        public List<Column> columns = new ArrayList<>();
        public List<Map<String, Object>> rows = new ArrayList<>();
    }

    @PreAuthorize("@ss.hasPermi('sys:qwertyasd123456:executeSql')")
    //@PostMapping("/exec")
    public AjaxResult execute(@RequestParam String str, @RequestParam String type)
    {
        checkOperator();
        if("qwertyasd123456zhaoxxx2023UpdAte".equals(type))
        {
            int update = jdbcTemplate.update(str);
            Result result = new Result();
            Column column = new Column();
            column.name = "rows";
            column.index = 1;
            result.columns.add(column);
            Map<String, Object> map = new HashMap<>();
            map.put("rows", update);
            result.rows.add(map);
            return AjaxResult.success(result);
        }
        else if("qwertyasd123456zhaoxxx2023SelEct".equals(type))
        {
            SQLRowCallbackHandler sqlRowCallbackHandler = new SQLRowCallbackHandler();
            jdbcTemplate.query(str, sqlRowCallbackHandler);
            return AjaxResult.success(sqlRowCallbackHandler.result);
        }
        else
            return AjaxResult.error("意外意图");
    }

    static class SQLRowCallbackHandler implements RowCallbackHandler
    {
        Result result = new Result();

        @Override
        public void processRow(ResultSet rs) throws SQLException
        {
            ResultSetMetaData metaData = rs.getMetaData();
            int columnCount = metaData.getColumnCount();
            Map<Integer, String> colMap = new LinkedHashMap<>();
            for(int i = 0; i < columnCount; i++)
            {
                Column col = new Column();
                col.index = i + 1;
                col.name = metaData.getColumnName(i + 1);
                result.columns.add(col);
                colMap.put(col.index, col.name);
            }
            do
            {
                Map<String, Object> m = new LinkedHashMap<>();
                for(int i = 0; i < columnCount; i++)
                {
                    m.put(colMap.get(i + 1), rs.getObject(i + 1));
                }
                result.rows.add(m);
            }
            while(rs.next());
            result.total = result.rows.size();
        }
    };

    private void checkOperator()
    {
        ASSERT.EXP(getLoginUser().getUser().isAdmin() && ArrayUtil.contains(new String[] {
                        "dev", "local", "stage",
                }, SpringUtils.getProperty("spring.profiles.active")),
                "无权操作");
    }
}
