//package jj.tech.paolu.biz.demo.controller;
//
//import static org.mybatis.dynamic.sql.SqlBuilder.select;
//
//import java.net.URI;
//import java.nio.file.Path;
//import java.nio.file.Paths;
//import java.util.ArrayList;
//import java.util.Comparator;
//import java.util.HashMap;
//import java.util.List;
//import java.util.Map;
//import java.util.Set;
//import java.util.concurrent.atomic.AtomicInteger;
//import java.util.stream.Collectors;
//import java.util.stream.Stream;
//
//import org.apache.commons.lang3.StringUtils;
//import org.jooq.DSLContext;
//import org.mybatis.dynamic.sql.render.RenderingStrategies;
//import org.springframework.aop.support.AopUtils;
//import org.springframework.beans.factory.ListableBeanFactory;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.jdbc.core.JdbcTemplate;
//import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
//import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
//import org.springframework.jdbc.core.namedparam.SqlParameterSource;
//import org.springframework.stereotype.Controller;
//import org.springframework.transaction.annotation.Transactional;
//import org.springframework.web.bind.annotation.GetMapping;
//import org.springframework.web.bind.annotation.RequestMapping;
//import org.springframework.web.bind.annotation.RestController;
//import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
//import org.springframework.web.util.UriComponents;
//import org.springframework.web.util.UriComponentsBuilder;
//
//import com.fasterxml.jackson.databind.ObjectMapper;
//
//import jj.tech.paolu.repository.mybatis.dao.SysUrlsMapper;
//import jj.tech.paolu.repository.mybatis.dao.UserInfoMapper;
//import jj.tech.paolu.repository.mybatis.dao.support.SysUrlsDynamicSqlSupport;
//import jj.tech.paolu.repository.mybatis.entity.SysUrls;
//
//
//@RestController
//@RequestMapping(value="/ttt")
//public class TestController {
//
//	@Autowired UserInfoMapper userInfoMapper;
//	@Autowired SysUrlsMapper sysUrlsMapper;
//	
//	@Autowired DSLContext dsl;
//	@Autowired JdbcTemplate jdbcTemplate;
//	@Autowired ListableBeanFactory listableBeanFactory;	//获取实时扫描运行的bean,性能较低
//	@Autowired RequestMappingHandlerMapping requestMappingHandlerMapping;
//	
//
//
//	@GetMapping(value = "/test", name="测试")
//	public void text() {
//
//	}
//	
//	@GetMapping(value="/url", name = "....")
//	@Transactional
//	public Object url() {
//		
//		//1 获取所有controller的url
//		final List<Object[]> list = new ArrayList<Object[]>();
//		requestMappingHandlerMapping
//		.getHandlerMethods()
//		.forEach((requestMappingInfo,handlerMethod) -> {
//	    	requestMappingInfo
//	    		.getPathPatternsCondition()
//	    		.getPatternValues()
//	    		.forEach((url)->{
//	    			RequestMapping mapping = handlerMethod.getMethodAnnotation(RequestMapping.class);
//	    			String name = mapping.name();
//	    			if(StringUtils.isAllBlank(name)) {
//	    				name = handlerMethod.getMethod().getName();
//	    			}
//	    			Object[] arry = {null, null, 1, 0, url, name,  handlerMethod.toString()};
//	    			list.add(arry);
//		    	});
//	    } );
//		
//		
//		//按url字符大小ascii排序, 再去重
//		HashMap<Object, Boolean> map = new HashMap<>();
//		List<Object[]> urls = list.stream()
//			.sorted(
//					(a,b)-> {
//						return a[4].toString().compareTo(b[4].toString());
//					}
//			)
//			.filter(i->{
//				return map.putIfAbsent(i[4], Boolean.TRUE) == null;
//			})
//			.collect(Collectors.toList());
//
//		
//		
//		
//		//2 构建父节点，菜单类型
//		Map<String,Object[]>  parentUrlMap = new HashMap<String,Object[]>();
//		Object[] arry0 = {1, 0, 2, 0, "#/", "boot", null};
//		parentUrlMap.put("#/", arry0);
//		AtomicInteger id = new AtomicInteger(2);
//		
//		
//		//3 添加ID和父节点的所有Url
//		List<Object[]> sonUrl = new ArrayList<Object[]>();
//		
//		urls.forEach(arr->{
//			String url = arr[4].toString();
//			Object name = arr[5];
//			Object method = arr[6];
//			List<String> parents = getAllParents(url);
//			int level = 1;
//			for(int i=parents.size()-1; i>=0; i--) {
//				
//				String item = parents.get(i);
//				if(i== parents.size()-1) {	//最终父节点
//					continue;
//				}
//				
//				if(i==0) {	//最小节点
//					String parent = "#"+parents.get(i+1);//获取父节点
////					System.err.println(parent+parentUrlMap.get(parent));
//					Object pid = parentUrlMap.get(parent)[0];
//					Object[] arry = {id.getAndIncrement(), pid, 1, level, item, name, method};
//					sonUrl.add(arry);
//					continue;
//				}
//				
//				if(!parentUrlMap.containsKey("#"+item)) {
//					String parent = "#"+parents.get(i+1);//获取父节点
//					Object pid = parentUrlMap.get(parent)[0];
//					Object[] arry = {id.getAndIncrement(), pid, 2, level, "#"+item, null, null};
//					parentUrlMap.put("#"+item, arry);
//				}
//				level++;
//				
//			}
//		});
//		
//		
//		//4 将controller上的@RequestMapping(value="", name="一级菜单"), 的name赋值给构建的菜单parentUrlMap
//		Map<String, String> menus= new HashMap<String, String>();
//		
//		Map<String, Object> controllers  = listableBeanFactory.getBeansWithAnnotation(Controller.class);
//		controllers.forEach((k,v)->{
//			Class<?> source = AopUtils.getTargetClass(v);//获取实际类，而不是spring的代理类
//			RequestMapping mapping = source.getAnnotation(RequestMapping.class);
//			if(mapping != null) {
//				String mappingurl = mapping.value()[0];
//				if(!StringUtils.startsWith(mappingurl, "/")) {
//					mappingurl = "/" +mappingurl;
//				}
//				mappingurl = "#"+mappingurl;
//				
//				String name  = mapping.name();
//				
//				String value = menus.get(mappingurl);
//				if(menus.containsKey(mappingurl)) {
//					//按名称ascii小的顺序赋值
//					if(StringUtils.isNoneBlank(name)  && name.compareTo(value)<0) {
//						menus.put(mappingurl, name);
//					}
//				}else {
//					if(StringUtils.isNoneBlank(name)) {
//						menus.put(mappingurl, name);
//					}
//				}
//				
//			}
//		});
//		
//		//赋值
//		menus.forEach((k,v)->{
//			Object[] arr = parentUrlMap.get(k);
//			if(arr!=null) {
//				arr[5]=v;
//			}
//		});
//
//		
//		List<Object[]> parentUrl = parentUrlMap.entrySet()
//				.stream()
//				.map(v->v.getValue())
//				.collect(Collectors.toList());
//		
//
//		jdbcTemplate.execute("TRUNCATE TABLE sys_urls");
//		String sql = "INSERT INTO sys_urls (ID,PID,TYPES,LEVEL,URL,NAME,METHOD) VALUES (?,?,?,?,?,?,?)";
//		jdbcTemplate.batchUpdate(sql, sonUrl);
//		jdbcTemplate.batchUpdate(sql, parentUrl);
//
//		return "ok";
//	}
//	
//	
//	
//	/**
//	 * @param uri ="/aa/bb/cc"
//	 * @return /aa/bb/cc, /aa/bb, /aa, /
//	 */
//	public static List<String> getAllParents(String uri){
//		if(StringUtils.isBlank(uri)) {
//			return List.of("");
//		}
//		UriComponents components = UriComponentsBuilder.fromUriString("file://"+uri).build();
//		URI u = components.toUri();
//		
//		List<String> urilist = components.getPathSegments();
//		
//		List<Path> paths = new ArrayList<Path>();
//		Path path = Paths.get(u);
//		paths.add(path);
//		
//		for(int i=0; i<urilist.size(); i++) {
//			Path parent =paths.get(i).getParent();
//			paths.add(parent);
//		}
//		
//		return paths.stream().map(pa->{
//			return pa.toString().replace("\\", "/");
//		}).toList();
//	}
//	
//	
//	
//	public Map<String,SysUrls> getAll(){
//		var provider = select(SysUrlsMapper.selectList)
//				.from(SysUrlsDynamicSqlSupport.sysUrls)
//				.build()
//				.render(RenderingStrategies.MYBATIS3);
//		List<SysUrls> allList = sysUrlsMapper.selectMany(provider);
//		
//		Map<String,SysUrls>  map = allList.stream().collect(
//				Collectors.toMap(SysUrls::getUrl, v->v));
//		return map;
//	}
//	
//	
//	
//	public void updataMenu(Map<String,SysUrls> db, Map<String,Object[]> parent, Map<String,Object[]> url) {
//		NamedParameterJdbcTemplate namejdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);
//		
//		
//		Map<String,SysUrls> dbwaitDelete = new HashMap<String,SysUrls>();
//		
//		Map<String,Object[]> all = 
//			Stream.of(parent,url)
//			.flatMap(map->map.entrySet().stream())
//			.collect(Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue));
//		
//		Map<String,Object[]> allAdd = new HashMap<String,Object[]>();
//		Map<String,Object[]> allUpdate = new HashMap<String,Object[]>();
//		
//		//1、菜单在数据库不存在则新增加,存在则更新
//		all.entrySet().stream().forEach(set->{
//			SysUrls bean = db.get(set.getKey());
//			if(bean==null) {
//				allAdd.put(set.getKey(), set.getValue());
//			}else {
//				Object[] arr = set.getValue();
//				Object[] up = new Object[] {arr[1],arr[2],arr[3],arr[5],arr[6],arr[4]};
//				allUpdate.put(set.getKey(), up);
//			}
//		});
//		
//		//2、数据库存在的菜单,在程序里不存在的,删除
//		db.entrySet().stream().forEach(set->{
//			String key = set.getKey();
//			Object[] arr = all.get(key);
//			if(arr==null) {
//				dbwaitDelete.put(key, set.getValue());
//			}
//		});
//		
//		
//		List<Object[]> add = allAdd.entrySet()
//				.stream()
//				.map(v->v.getValue())
//				.collect(Collectors.toList());
//		
//		String addsql = "INSERT INTO SYS_URLS (ID,PID,TYPES,LEVEL,URL,NAME,METHOD) VALUES (?,?,?,?,?,?,?)";
//		jdbcTemplate.batchUpdate(addsql, add);
//		
//		
//		List<Object[]> update = allUpdate.entrySet()
//				.stream()
//				.map(v->v.getValue())
//				.collect(Collectors.toList());
//		String updatesql = "UPDATE SYS_URLS SET PID=?,TYPES=?,LEVEL=?,NAME=?,METHOD=? WHERE URL=?";
//		
//		update.forEach(i->{
//			System.out.println(i[3]+" == "+i[5]);
//		});
//		jdbcTemplate.batchUpdate(updatesql, update);
//		
//		
//		//删除
//		if(dbwaitDelete.size()>0) {
//			Set<String> urls = dbwaitDelete.keySet();
//			
//			MapSqlParameterSource parameters = new MapSqlParameterSource();
//	        parameters.addValue("urls", urls);
//	        String deletesql = "DELETE SYS_URLS WHERE URL IN (:urls)";
//	        namejdbcTemplate.update(deletesql, parameters);
//		}
//		
//	}
//	
//
//}