package com.tykj.workflowcore;


import com.alibaba.fastjson.JSON;
import com.tykj.workflowcore.model_layer.controller.ModelController;
import com.tykj.workflowcore.model_layer.dao.ColumnInfoDao;
import com.tykj.workflowcore.model_layer.dao.TableInfoDao;
import com.tykj.workflowcore.model_layer.dao.TableInfoExDao;
import com.tykj.workflowcore.model_layer.entity.ColumnInfo;
import com.tykj.workflowcore.model_layer.entity.TableInfo;
import com.tykj.workflowcore.model_layer.entity.vo.TableAndColumnInfoVO;
import com.tykj.workflowcore.model_layer.myEnum.ModelType;
import com.tykj.workflowcore.model_layer.service.ModelService;
import com.tykj.workflowcore.model_layer.service.impl.ModelHelper;
import com.tykj.workflowcore.model_layer.utils.AggregationUtil;
import com.tykj.workflowcore.model_layer.utils.CreateTableUtil;
import com.tykj.workflowcore.model_layer.utils.SessionUtil;
import org.aspectj.lang.annotation.Before;
import org.dom4j.*;
import org.dom4j.io.SAXReader;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.internal.SessionImpl;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.query.NativeQuery;
import org.hibernate.query.Query;
import org.hibernate.tool.hbm2ddl.SchemaUpdate;
import org.hibernate.tool.schema.TargetType;
import org.json.JSONObject;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.result.HandlerResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.util.StringUtils;


import javax.persistence.CascadeType;
import javax.persistence.EntityManagerFactory;
import java.io.ByteArrayInputStream;
import java.util.*;

import static com.tykj.workflowcore.model_layer.utils.CreateTableUtil.getTypeName;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.not;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
class WorkflowCoreApplicationTests {

    @Autowired
    ModelController modelController;

    @Autowired
    JdbcTemplate jdbcTemplate;

    @Autowired
    TableInfoDao tableInfoDao;

    @Autowired
    MockMvc mockMvc;

    @Autowired
    ModelService modelService;

    @Autowired
    MetadataSources metadataSources;

    @Autowired
    EntityManagerFactory entityManagerFactory;


    @Autowired
    SessionUtil sessionUtil;

    @Autowired
    ModelHelper modelHelper;

    @Autowired
    TableInfoExDao tableInfoExDao;

    @Autowired
    ColumnInfoDao columnInfoDao;

    @Before("")
    public void setUp() {
        mockMvc = MockMvcBuilders.standaloneSetup(modelController).build();
    }

    @Test
    void contextLoads() {
        System.out.println("11111111111111111111111");

    }
//#####################################模型层测试 start##############################################

    RequestBuilder request;

    /**
     * 测试表的条件查询
     *
     * @throws Exception
     */
    @Test
    public void SearchTableVOTest() throws Exception {

        String SearchTableinfo_Json = "{\n" +
                "    \"modelName\":\"\",\n" +
                "    \"modelTitle\":\"\",\n" +
                "    \"modelType\":\"\"\n" +
                "}";
        request = post("/model/getAllEntity/")
                .contentType(MediaType.APPLICATION_JSON)
                .content(SearchTableinfo_Json)
                // 设置返回值类型为utf-8，否则默认为ISO-8859-1
                .accept(MediaType.APPLICATION_JSON_UTF8_VALUE);
        mockMvc.perform(request).andExpect(status().isOk())
                .andExpect(content().string(not("")))  //条件
                .andExpect(content().string(not("[]")))
                .andDo(print());//打印输出结果

    }

    /**
     * 测试列条件查询
     *
     * @throws Exception
     */
    @Test
    public void testSearchColumnVO() throws Exception {

        String searchColumnV0_json = "{\n" +
                "\"dbId\":2\n" +
                "}";

        String searchColumnV0_json2 = "{\n" +
                "\"dbName\":\"sy_order\"\n" +
                "}";
        request = post("/model/getAllField/")
                .contentType(MediaType.APPLICATION_JSON)
                .content(searchColumnV0_json2)
                // 设置返回值类型为utf-8，否则默认为ISO-8859-1
                .accept(MediaType.APPLICATION_JSON_UTF8_VALUE);

        mockMvc.perform(request).andExpect(status().isOk())
                .andExpect(content().string(not("")))
                .andExpect(content().string(not("[]")))
                .andDo(print());//打印输出结果
    }

    /**
     * 测试新增对象
     *
     * @throws Exception
     */
    @Test
    public void addModelTest() throws Exception {

        String TableVo_json = "{\n" +
                "\"modelName\":\"people\",\n" +
                "\"modelTitle\":\"人\",\n" +
                "\"modelType\":1,\n" +
                "\"parentTable\":\"\",\n" +
                "\"description\":\"详细信息\",\n" +
                "\"dataList\":[\n" +
                "    {\"fieldName\": \"c1\", \"fieldTitle\": \"列1\", \"fieldType\": \"java.lang.String\", \"fieldLength\": \"255\"},\n" +
                "    {\"fieldName\": \"c2\", \"fieldTitle\": \"列2\", \"fieldType\": \"java.lang.String\", \"fieldLength\": \"255\"}\n" +
                "]\n" +
                "}";
        request = post("/model/addModel/")
                .contentType(MediaType.APPLICATION_JSON)
                .content(TableVo_json)
                // 设置返回值类型为utf-8，否则默认为ISO-8859-1
                .accept(MediaType.APPLICATION_JSON_UTF8_VALUE);

        mockMvc.perform(request).andExpect(status().isOk())
                .andExpect(content().string(not("")))
                .andExpect(content().string(not("[]")))
                .andExpect(content().string(equalTo("{\"message\":\"新建成功!\",\"data\":\"\"}")))
                .andDo(print());//打印输出结果
    }

    /**
     * 测试插入数据
     *
     * @throws Exception
     */
    @Test
    public void insertValuesByTableName() throws Exception {
        String values_json = "{\"techer\":{\"name\": \"zhangsan\",\"age\" :\"20\"}}";

        request = post("/model/insertValues/")
                .contentType(MediaType.APPLICATION_JSON)
                .content(values_json)
                // 设置返回值类型为utf-8，否则默认为ISO-8859-1
                .accept(MediaType.APPLICATION_JSON_UTF8_VALUE);

        mockMvc.perform(request).andExpect(status().isOk())
                .andExpect(content().string(not("")))
                .andExpect(content().string(not("[]")))
                .andExpect(content().string(equalTo("{\"message\":\"数据插入成功\",\"data\":\"\"}")))
                .andDo(print());//打印输出结果
    }

    /**
     * 测试查询全部
     *
     * @throws Exception
     */
    @Test
    public void findAllByTableName() throws Exception {
        request = get("/model/getAll/")
                .param("tableName", "techer")
                .accept(MediaType.APPLICATION_JSON_UTF8_VALUE);

        mockMvc.perform(request)
                .andExpect(status().isOk())
                .andExpect(content().string(not("")))
                .andDo(print());

    }


    /**
     * 测试删除表
     */
    @Test
    public void testDelTable() throws Exception {
        request = delete("/model/delete/")
                .param("id", "5")
                .accept(MediaType.APPLICATION_JSON_UTF8_VALUE);
        mockMvc.perform(request)
                .andExpect(status().isOk())
                .andExpect(content().string(not("")))
                .andDo(print());
    }

    @Test
    public void testAll() {
/*
        Integer[] ids = {2, 3, 22};
        List<Integer> integers = Arrays.asList(ids);

        Object[] objects = integers.toArray();
        TableAndColumnInfoVO all = modelService.getTableInfoAndColumnInfoByBatch(ids);
        System.out.println(all);
*/

        String xml =
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                        "<!DOCTYPE hibernate-mapping PUBLIC\n" +
                        "        \"-//Hibernate/Hibernate Mapping DTD 3.0//EN\"\n" +
                        "        \"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd\">\n" +
                        "<hibernate-mapping>\n" +
                        "    <class entity-name=\"teacher\" table=\"teacher\">\n" +
                        " <id name=\"id\" type=\"java.lang.Integer\" length=\"11\" unsaved-value=\"null\">\n" +
                        "            <generator class=\"identity\" />\n" +
                        "        </id> <property type=\"java.lang.Integer\" name=\"id\" length=\"11\" column=\"id\"/>\n" +
                        " <property type=\"java.lang.String\" name=\"name\" length=\"255\" column=\"name\"/>\n" +
                        " <property type=\"java.lang.Integer\" name=\"age\" length=\"11\" column=\"age\"/>\n" +
                        " <property type=\"java.lang.String\" name=\"sex\" length=\"255\" column=\"sex\"/>\n" +
                        "\n" +
                        "  <set name=\"students\" table=\"stu_teacher_ref\" >\n" +
                        " \t<key column=\"id\"/>\n" +
                        " \t<many-to-many class=\"stu\" column=\"\"/>\n" +
                        " </set>\n" +
                        "\n" +
                        "   </class>\n" +
                        "</hibernate-mapping>";
        SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);
        StandardServiceRegistry serviceRegistry = sessionFactory.getSessionFactoryOptions().getServiceRegistry();
        MetadataSources metadataSources = new MetadataSources(serviceRegistry);
        sessionFactory.getSessionFactoryOptions();
        metadataSources.addInputStream(new ByteArrayInputStream(xml.getBytes()));
        Metadata metadata = metadataSources.buildMetadata();
        //更新数据库Schema,如果不存在就创建表,存在就更新字段,不会影响已有数据
        SchemaUpdate schemaUpdate = new SchemaUpdate();
        schemaUpdate.execute(EnumSet.of(TargetType.DATABASE), metadata, serviceRegistry);

        metadata = metadataSources.buildMetadata();
        //创建会话工厂
        SessionFactory newSessionFactory = metadata.buildSessionFactory();
        //保存对象
        Session newSession = newSessionFactory.openSession();
        Query query = newSession.createQuery("");
        List list = query.list();
        list.forEach(o -> System.out.println(o));


    }

    @Test
    public void testxml() {
        String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                "<!DOCTYPE hibernate-mapping PUBLIC\n" +
                "        \"-//Hibernate/Hibernate Mapping DTD 3.0//EN\"\n" +
                "        \"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd\">\n" +
                "<hibernate-mapping>\n" +
                "    <class entity-name=\"p_c\" table=\"people\">\n" +
                " <id name=\"id\" type=\"java.lang.Integer\" length=\"11\" unsaved-value=\"null\">\n" +
                "            <generator class=\"identity\" />\n" +
                "        </id> <property type=\"java.lang.String\" name=\"name\" length=\"255\" column=\"name\"/>\n" +
                " <property type=\"java.lang.String\" name=\"phone\" length=\"255\" column=\"phone\"/>\n" +
                "\n" +
                " <set name=\"carList\" cascade=\"save-update\">\n" +
                "     <key column=\"p_id\"/>\n" +
                "     <one-to-many class=\"car\"/>\n" +
                "</set>\n" +
                "   </class>\n" +
                "</hibernate-mapping>";
        sessionUtil.addXml(xml);
        Session session = sessionUtil.getSession();
        HashMap hashMap = new HashMap();
        HashMap carMap = new HashMap();
        Set arrayList = new HashSet();
        hashMap.put("name", "张三");
        hashMap.put("phone", "李四");
        carMap.put("name", "车1");
        carMap.put("card", 1);
        arrayList.add(carMap);

        SessionImpl news = (SessionImpl) session;


        hashMap.put("carList", arrayList);
        session.save("p_c", hashMap);
        session.getTransaction().begin();
        session.getTransaction().commit();
//        session.close();
        Query from_p_c = session.createQuery("from p_c");
        List list = from_p_c.list();
        for (Object o : list) {
            System.out.println(o);
        }

        System.out.println("1");
    }

    @Test
    public void testOneToOne() {
        String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                "<!DOCTYPE hibernate-mapping PUBLIC\n" +
                "        \"-//Hibernate/Hibernate Mapping DTD 3.0//EN\"\n" +
                "        \"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd\">\n" +
                "<hibernate-mapping>\n" +
                "    <class entity-name=\"husband_wife\" table=\"wife\">\n" +
                " <id name=\"id\" type=\"java.lang.Integer\" length=\"11\" unsaved-value=\"null\">\n" +
                "            <generator class=\"identity\" />\n" +
                "        </id> <property type=\"java.lang.String\" name=\"name\" length=\"255\" column=\"name\"/>\n" +
                " <property type=\"java.lang.String\" name=\"age\" length=\"255\" column=\"age\"/>\n" +
                "  <one-to-one name=\"wife_id\" class=\"husband\" cascade=\"save-update\"/>\n" +
                "   </class>\n" +
                "</hibernate-mapping>";

        sessionUtil.addXml(xml);
        Session session = sessionUtil.getSession();
        Query query = session.createQuery("from  husband_wife");
        List list = query.list();
        list.forEach(o -> System.out.println(o));
    }


    @Test
    public void testManyToMany() {
        String xml = "" +
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                "<!DOCTYPE hibernate-mapping PUBLIC\n" +
                "        \"-//Hibernate/Hibernate Mapping DTD 3.0//EN\"\n" +
                "        \"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd\">\n" +
                "<hibernate-mapping>\n" +
                "    <class entity-name=\"stu_teacher_ref\" table=\"stus\">\n" +
                " <id name=\"id\" type=\"java.lang.Integer\" length=\"11\" unsaved-value=\"null\">\n" +
                "            <generator class=\"identity\" />\n" +
                "        </id> <property type=\"java.lang.String\" name=\"name\" length=\"255\" column=\"name\"/>\n" +
                " <property type=\"java.lang.String\" name=\"age\" length=\"255\" column=\"age\"/>\n" +
                " <property type=\"java.lang.String\" name=\"sex\" length=\"255\" column=\"sex\"/>\n" +
                " <property type=\"java.lang.String\" name=\"laike\" length=\"255\" column=\"laike\"/>\n" +
                " <set name=\"teacher\" table=\"stu_teacher_ref\">\n" +
                " \t<key column=\"student_id\"/>\n" +
                " \t<many-to-many class=\"teacher\" column=\"teacher_id\"/>\n" +
                " </set>\n" +
                "\n" +
                "   </class>\n" +
                "</hibernate-mapping>";

        sessionUtil.addXml(xml);
        Session session = sessionUtil.getSession();

        Query from_stus = session.createQuery("from stu_teacher_ref");
        List list = from_stus.list();
        System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
        list.forEach(o -> System.out.println(o));
        System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
    }

    @Test
    public void tsetXMLOBJ() throws DocumentException {

        String xml = "" +
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                "<!DOCTYPE hibernate-mapping PUBLIC\n" +
                "        \"-//Hibernate/Hibernate Mapping DTD 3.0//EN\"\n" +
                "        \"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd\">\n" +
                "<hibernate-mapping>\n" +
                "    <class entity-name=\"stu_teacher_ref\" table=\"stus\">\n" +
                " <id name=\"id\" type=\"java.lang.Integer\" length=\"11\" unsaved-value=\"null\">\n" +
                "            <generator class=\"identity\" />\n" +
                "        </id> <property type=\"java.lang.String\" name=\"name\" length=\"255\" column=\"name\"/>\n" +
                " <property type=\"java.lang.String\" name=\"age\" length=\"255\" column=\"age\"/>\n" +
                " <property type=\"java.lang.String\" name=\"sex\" length=\"255\" column=\"sex\"/>\n" +
                " <property type=\"java.lang.String\" name=\"laike\" length=\"255\" column=\"laike\"/>\n" +
                " <set name=\"teacher\" table=\"stu_teacher_ref\">\n" +
                " \t<key column=\"student_id\"/>\n" +
                " \t<many-to-many class=\"teacher\" column=\"teacher_id\"/>\n" +
                " </set>\n" +
                "\n" +
                "   </class>\n" +
                "</hibernate-mapping>";

        //创建解析器
        Document document = DocumentHelper.parseText(xml);
        Element classMapping = document.getRootElement().elements().get(0);
        String set = " <set name=\"teacher\" table=\"stu_teacher_ref\">\n" +
                " \t<key column=\"student_id\"/>\n" +
                " \t<many-to-many class=\"teacher\" column=\"teacher_id\"/>\n" +
                " </set>\n";
        classMapping.addElement(set);
        System.out.println(classMapping);
        Element id = classMapping.element("id");
        System.out.println(id);
        List<Element> elements = classMapping.elements("property");
        for (Element element : elements) {
            System.out.println(element);
        }
    }

    @Test
    public void testOldProperty() throws DocumentException {

        TableInfo stus = tableInfoDao.findByModelName("stus");
        String xml = stus.getXml();

        Document document = DocumentHelper.parseText(xml);
        List<Element> elements = document.getRootElement().elements().get(0).elements();

        for (Element element : elements) {
            System.out.println(element.asXML());
        }
    }

    //    @Test
//    public void tsetCreateXml1(){
//        TableInfo wife = tableInfoDao.findByModelName("car");
////        System.out.println(wife);
//        String s = AggregationUtil.addOneToOne("wife_id", "husband", wife.getXml());
//        System.out.println(s);
//    }
//    @Test
//    public void tsetCreateXml2(){
//        TableInfo people = tableInfoDao.findByModelName("people");
//        String xml = people.getXml();
//
//        String s = AggregationUtil.addOneToMany("people", "car", "p_id", xml);
//        System.out.println(s);
//    }
//    @Test
//    public void tsetCreateXml3(){
//        TableInfo teacher = tableInfoDao.findByModelName("teacher");
//
//        String xml = teacher.getXml();
//        String s = AggregationUtil.addManyToMany("teacher", "stus", xml);
//        System.out.println(s);
//    }
    @Test
    public void testJSON() {
        String xml = tableInfoExDao.findById(32).get().getXml();
        sessionUtil.addXml(xml);
        Session session = sessionUtil.getSession();
        List list = session.createQuery("from  test_obj").list();
        System.out.println(list);

//        String jsonExample = modelHelper.getJsonExample(2);
//        System.out.println(jsonExample);
        StringUtils.hasLength(xml);
    }
    @Test
    public void  testDelete(){
        List<TableInfo> tableInfos = tableInfoDao.deleteAllByModelType(0);
        for (TableInfo tableInfo : tableInfos) {
            System.out.println(tableInfo.getId());
            columnInfoDao.deleteAllByDbId(tableInfo.getId());
        }

    }
    @Test
    public void testType(){
        System.out.println(getTypeName(Integer.class.toString()));
    }

}
