package com.purui.prims.headless.server.rest;

import com.purui.prims.auth.api.authentication.pojo.User;
import com.purui.prims.auth.api.authentication.utils.UserHolder;
import com.purui.prims.headless.api.pojo.request.DatabaseReq;
import com.purui.prims.headless.api.pojo.request.SqlExecuteReq;
import com.purui.prims.headless.api.pojo.response.DatabaseResp;
import com.purui.prims.headless.api.pojo.response.SemanticQueryResp;
import com.purui.prims.headless.core.pojo.DBColumn;
import com.purui.prims.headless.server.pojo.DatabaseParameter;
import com.purui.prims.headless.server.service.DatabaseService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/semantic/database")
@Api(tags = "数据库管理")
public class DatabaseController {


    private DatabaseService databaseService;

    public DatabaseController(DatabaseService databaseService) {
        this.databaseService = databaseService;
    }

    @ApiOperation(value = "测试连接")
    @PostMapping("/testConnect")
    public boolean testConnect(@RequestBody DatabaseReq databaseReq,
                               HttpServletRequest request,
                               HttpServletResponse response) {
        User user = UserHolder.findUser(request, response);
        return databaseService.testConnect(databaseReq, user);
    }

    @ApiOperation(value = "创建或更新数据源")
    @PostMapping("/createOrUpdateDatabase")
    public DatabaseResp createOrUpdateDatabase(@RequestBody DatabaseReq databaseReq,
                                               HttpServletRequest request,
                                               HttpServletResponse response) {
        User user = UserHolder.findUser(request, response);
        return databaseService.createOrUpdateDatabase(databaseReq, user);
    }

    @ApiOperation(value = "获取数据源详情")
    @GetMapping("/{id}")
    public DatabaseResp getDatabase(@PathVariable("id") Long id, HttpServletRequest request,
                                    HttpServletResponse response) {
        User user = UserHolder.findUser(request, response);
        return databaseService.getDatabase(id, user);
    }

    @ApiOperation(value = "获取数据源列表")
    @GetMapping("/getDatabaseList")
    public List<DatabaseResp> getDatabaseList(HttpServletRequest request,
                                              HttpServletResponse response) {
        User user = UserHolder.findUser(request, response);
        return databaseService.getDatabaseList(user);
    }

    @ApiOperation(value = "删除数据源")
    @DeleteMapping("/{id}")
    public boolean deleteDatabase(@PathVariable("id") Long id) {
        databaseService.deleteDatabase(id);
        return true;
    }

    @ApiOperation(value = "执行SQL", notes = "通过执行SQL，返回所有的列元数据（含字段类型）")
    @PostMapping("/executeSql")
    public SemanticQueryResp executeSql(@RequestBody SqlExecuteReq sqlExecuteReq,
                                        HttpServletRequest request,
                                        HttpServletResponse response) {
        User user = UserHolder.findUser(request, response);
        return databaseService.executeSql(sqlExecuteReq, sqlExecuteReq.getId(), user);
    }

    @ApiOperation(value = "获取所有数据库名")
    @GetMapping("/getDbNames/{id}")
    public List<String> getDbNames(@PathVariable("id") Long id) throws SQLException {
        return databaseService.getDbNames(id);
    }

    @ApiOperation(value = "获取所有表名")
    @GetMapping("/getTables/{id}/{db}")
    public List<String> getTables(@PathVariable("id") Long id,
                                       @PathVariable("db") String db) throws SQLException {
        return databaseService.getTables(id, db);
    }

    @ApiOperation(value = "获取所有列名")
    @GetMapping("/getColumns/{id}/{db}/{table}")
    public List<DBColumn> getColumns(@PathVariable("id") Long id,
                                     @PathVariable("db") String db,
                                     @PathVariable("table") String table) throws SQLException {
        return databaseService.getColumns(id, db, table);
    }

    @ApiOperation(value = "获取支持的数据库类型")
    @GetMapping("/getDatabaseParameters")
    public Map<String, List<DatabaseParameter>> getDatabaseParameters(HttpServletRequest request,
                                                                      HttpServletResponse response) {
        return databaseService.getDatabaseParameters();
    }

}
