package cn.edu.whu.boot.xml.controller;

import cn.edu.whu.boot.xml.service.ITableService;
import cn.edu.whu.boot.common.domain.StatusCode;
import cn.edu.whu.boot.common.utils.xml.GenerateSqlUtil;
import cn.edu.whu.boot.common.utils.collection.OtherUtil;
import cn.edu.whu.boot.common.domain.ResultMessage;
import cn.edu.whu.boot.xml.domain.Task;
import cn.edu.whu.boot.xml.domain.XmlEnity;
import cn.edu.whu.boot.xml.service.ITaskService;
import cn.edu.whu.boot.xml.service.IXmlEnityService;
import cn.edu.whu.boot.xml.xmlreader.bean.Config;
import cn.edu.whu.boot.xml.xmlreader.bean.Field;
import cn.edu.whu.boot.xml.xmlreader.bean.Table;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 创建任务配置的数据库表，对应网页端任务管理中的任务创库按钮!!!
 * @author Zhou Chao
 */
@RestController
@RequestMapping("table")
public class DataBaseTableController{

    private final ITableService tableService;
    private final ITaskService taskService;
    private final IXmlEnityService xmlEnityService;

    @Autowired
    public DataBaseTableController(ITableService tableService, ITaskService taskService, IXmlEnityService xmlEnityService){
        this.tableService = tableService;
        this.taskService = taskService;
        this.xmlEnityService = xmlEnityService;
    }

    /**
     * 创建数据库表
     */
    @RequestMapping(value = "createTable", produces = "text/html;charset=UTF-8")
    public String createTable(Integer id){
        Task task = taskService.getTaskById(id);
        XmlEnity xmlEnity = xmlEnityService.getXmlEnityById(task.getXmlId());
        if(task.getHasCreateTables() == (short) 1){
            return ResultMessage.failed(StatusCode.FAILED.getStatus(),"hasCreated").toString();
        }

        boolean xmlFileIsModified = OtherUtil.checkXmlFileIsModified(xmlEnity);
        if(xmlFileIsModified){
            return ResultMessage.failed(StatusCode.FAILED_AND_SHOW.getStatus(),
                                        xmlEnity.getFileName().trim() + ".xml文件已被修改").toString();
        }

        tableService.createTableAndUpdateTask(task, xmlEnity, buildAllSqlString(task));
        return ResultMessage.success(null).toString();
    }

    /**
     * 删除旧的数据库表，再创建新的数据库表
     */
    @RequestMapping(value = "deleteAndCreateTable", produces = "text/html;charset=UTF-8")
    public String deleteAndCreateTable(Integer id){
        Task task = taskService.getTaskById(id);
        XmlEnity xmlEnity = xmlEnityService.getXmlEnityById(task.getXmlId());
        boolean xmlFileIsModified = OtherUtil.checkXmlFileIsModified(xmlEnity);
        if(xmlFileIsModified){
            return new ResultMessage<>(false, "xml文件被修改", null).toString();
        }
        tableService.createTableAndUpdateTask(task, xmlEnity, buildAllSqlString(task));
        return ResultMessage.success(null).toString();
    }

    /**
     * 判断某任务中是否存在多个空间对象表，该方法获取这些表名，后期需要创建于之对应的多媒体表
     */
    private List<String> getGeometryTablesName(Map<String, Table> tables){
        List<String> resultList = new ArrayList<>();
        for(Map.Entry<String, Table> entry : tables.entrySet()){
            Map<String, Field> fields = entry.getValue().getFields();
            for(Map.Entry<String, Field> fieldEntry : fields.entrySet()){
                if(fieldEntry.getValue().isGeometry()){
                    resultList.add(entry.getKey());
                    break;
                }
            }
        }
        return resultList;
    }

    /**
     * 构造一个完整的创建数据库表的 SQL
     */
    private String buildAllSqlString(Task task){
        JSONObject configJsonObject = JSON.parseObject(task.getConfig());
        Config config = JSON.toJavaObject(configJsonObject, Config.class);
        // 获取空间表名集合，后期用于创建多媒体表!!!
        List<String> geometryTableKeyList = getGeometryTablesName(config.getTables());
        return GenerateSqlUtil.generateSchemaCreateSql(task)
                + GenerateSqlUtil.generateDatabaseTableSql(task, false)
                + GenerateSqlUtil.generateDatabaseTableSql(task, true)
                + GenerateSqlUtil.generateMultiMediaSql(task, false, geometryTableKeyList)
                + GenerateSqlUtil.generateMultiMediaSql(task, true, geometryTableKeyList)
                + GenerateSqlUtil.generateRouteAndDraftSql(task);
    }
}
