package org.springblade.business.utils;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSON;
import org.apache.http.Consts;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import com.baomidou.mybatisplus.annotation.TableName;
import org.springblade.business.entity.DatumPoint;
import org.springblade.manager.entity.Formula;
import org.springblade.manager.entity.FormulaBase;
import org.springblade.manager.vo.FormulaType;

import javax.validation.constraints.Size;


/**
 * @author yangyj
 * @Date 2022/5/30 15:20
 * @description TODO
 */
public class FunctionMain {

    public static Matcher matcher(String regex, String value) {
        Pattern pattern = Pattern.compile(regex);
        return pattern.matcher(value);
    }
    public static String toMapper(Class<?> clazz) {
        StringBuilder sb = new StringBuilder();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field:fields) {
            field.setAccessible(true);
            if(field.getModifiers()== (Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL)){
                continue;
            }
            String property =field.getName();
            String column=property;
            String template="<result column=\"$1\" property=\"$2\"/>\n";
            Matcher m = matcher("[A-Z]",column);
            while (m.find()){
                String re=m.group();
                column=column.replace(re,"_"+re.toLowerCase(Locale.ROOT));
            }
            template= template.replace("$1",property).replace("$2",column);
            sb.append(template);
        }
       return sb.toString();
    }

    public static List<Field> collect(Class<?> clazz){
        Field[] fields = clazz.getDeclaredFields();
        return Arrays.stream(fields).filter(e->e.getModifiers()!= (Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL)).collect(Collectors.toList());
    }

    public static List<Field>  collectChain(Class<?> clazz,boolean fi ) {
        Class<?> su = clazz.getSuperclass();
        if(su!=null&&!Object.class.toString().equals(su.getName())&&fi){
            List<Field> total=new ArrayList<>();
            total.addAll(collectChain(su, true));
            total.addAll(collect(clazz));
            return total;
        }else{
            return  collect(clazz);
        }
    }

    public static String  builder(Class<?> clazz) {
        Class<?> su = clazz.getSuperclass();
        if(su!=null&&!Object.class.toString().equals(su.getName())){
             return builder(su)+toMapper(clazz);
        }else{
             return  toMapper(clazz);
        }
    }
    public static void getToken()  {
        HttpClient httpClient = HttpClientBuilder.create().build();
        HttpPost httpPost = new HttpPost("http://localhost/blade-auth/oauth/token");
        httpPost.setHeader("Authorization","Basic c2FiZXI6c2FiZXJfc2VjcmV0");
        httpPost.setHeader("Content-Type","application/x-www-form-urlencoded");
        httpPost.setHeader("Tenant-Id","000000");
        List<NameValuePair> params=new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("grant_type" , "password"));
        params.add(new BasicNameValuePair("username" , "admin"));
        params.add(new BasicNameValuePair("password" , "21232f297a57a5a743894a0e4a801fc3"));
        params.add(new BasicNameValuePair("scope" , "all"));
        params.add(new BasicNameValuePair("tenantId" , "000000"));
        httpPost.setEntity(new UrlEncodedFormEntity(params, Consts.UTF_8));
        try {
            HttpResponse httpResponse= httpClient.execute(httpPost);
            InputStream inputStream = httpResponse.getEntity().getContent();
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int index = 0;
            while ((index=inputStream.read(buffer))!=-1){
                outputStream.write(buffer,0,index);
            }
            System.out.println("\n");
            System.out.println("bearer "+ JSON.parseObject(outputStream.toString()).getString("access_token"));
            System.out.print("bearer "+ JSON.parseObject(outputStream.toString()).getString("refresh_token"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void createTable(Class<?> clazz,String remark) {
               String tableName=clazz.getAnnotation(TableName.class).value();
               StringBuilder sql = new StringBuilder( "DROP TABLE IF EXISTS `"+tableName+"`;\n");
               sql.append("CREATE TABLE `").append(tableName).append("` ( \n").append("`id` bigint(20) NOT NULL COMMENT '主键',\n");
               List<Field> fields=collectChain(clazz,false);
               for(Field f:fields){
                   Size s=f.getAnnotation(Size.class);
                   String column=f.getName();
                   String template=" `$1` $2 DEFAULT NULL,\n";
                   Matcher m = matcher("[A-Z]",column);
                   while (m.find()){
                       String re=m.group();
                       column=column.replace(re,"_"+re.toLowerCase(Locale.ROOT));
                   }
                   template=template.replace("$1",column);
                   String fieldName=f.getType().getCanonicalName();
                   if(fieldName.contains("String")){
                       int len=255;
                       if(s!=null){
                           len=s.max();
                       }else if(column.contains("_id")){
                           len=20;
                       }
                       template=template.replace("$2","varchar("+len+")");
                   }else  if(fieldName.contains("Integer")){
                       int len=2;
                       if(s!=null){
                           len=s.max();
                       }
                       template=template.replace("$2","int("+len+")");
                   }else  if(fieldName.contains("Double")){
                       template=template.replace("$2","double");
                   }else  if(fieldName.contains("Long")){
                       int len=20;
                       if(s!=null){
                           len=s.max();
                       }
                       template=template.replace("$2","bigint("+len+")");
                   }else  if(fieldName.contains("Date")){
                       template=template.replace("$2","datetime");
                   }
                   sql.append(template);
               }
               sql.append(
                       "  `tenant_id` varchar(12) DEFAULT '000000' COMMENT '租户ID',\n" +
                       " `create_user` bigint(20) DEFAULT NULL COMMENT '创建人',\n" +
                       "  `create_dept` bigint(20) DEFAULT NULL COMMENT '创建部门',\n" +
                       "  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n" +
                       "  `update_user` bigint(20) DEFAULT NULL COMMENT '修改人',\n" +
                       "  `update_time` datetime DEFAULT NULL COMMENT '修改时间',\n" +
                       "  `status` int(2) DEFAULT NULL COMMENT '状态',\n" +
                       "  `is_deleted` int(2) DEFAULT '0' COMMENT '是否已删除',");
               sql.append("  PRIMARY KEY (`id`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='").append(remark).append("'");
          System.out.println(sql);
    }

    public static void main(String[] args)  {
//        createTable(Formula.class,"公式配置");
//        System.out.println(builder(Formula.class));
//          getToken();
         DatumPoint dap = new DatumPoint();
         dap.setH(1.0);
         dap.setY(2.0);
         dap.setX(3.0);
         dap.setType(1);
         dap.setName("测试");
         dap.setLevel("一级");
         dap.setContractId(1L);
         dap.setProjectId(2L);
         dap.setRemark("导线点");
        System.out.println(JSON.toJSONString(dap));
    }


}
