package com.ylcm.sys.common;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;

import com.ylcm.sys.enums.MediaRankEnum;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class EnumHelperUtil {

	/**
	 * indexOf,传入的参数ordinal指的是需要的枚举值在设定的枚举类中的顺序，以0开始 T
	 */
	public static <T extends Enum<T>> T indexOf(Class<T> clazz, int ordinal) {
		return (T) clazz.getEnumConstants()[ordinal];
	}

	/**
	 * 根据枚举属性名称获取枚举对象
	 * 
	 * @param name 传入的参数name指的是枚举值的名称
	 * @return Enum T
	 */
	public static <T extends Enum<T>> T getByName(Class<T> clazz, String name) {

		return (T) Enum.valueOf(clazz, name);
	}

	/**
	 * @param clazz	对象class
	 * @param regex 枚举值的名称正则
	 * @oaram method 方法名称
	 */
	public static <T extends Enum<T>> T getOne(Class<T> clazz, String regex, String method, String val) {
		List<T> list = getList(clazz, regex, method, val);
		if(CollectionUtils.isEmpty(list)){
			return null;
		}
		return list.get(0);
	}
	
	public static <T extends Enum<T>> T getOneByName(Class<T> clazz, String name) {
		return getOne(clazz, "getName", name);
	}
	
	public static <T extends Enum<T>> T getOneByCode(Class<T> clazz, String code) {
		return getOne(clazz, "getCode", code);
	}
	
	public static <T extends Enum<T>> T getOne(Class<T> clazz, String method, String val) {
		if(StringUtils.isEmpty(method) || StringUtils.isEmpty(val)){
			return null;
		}
		List<T> list = new ArrayList<>();
		try {
			Method targetMethod = clazz.getDeclaredMethod(method);
			if(targetMethod == null){
				return null;
			}
			
			T[] enums = clazz.getEnumConstants();
			for (T t : enums) {
				if (val.toString().equals(targetMethod.invoke(t).toString())) {
					list.add(t);
				}
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		} 
		if(CollectionUtils.isEmpty(list)){
			return null;
		}
		return list.get(0);
	}
	
	/**
	 * 获取匹配的枚举对象
	 * @param clazz	对象class
	 * @param regex 枚举值的名称正则
	 * @oaram method 方法名称
	 * @param val 属性值
	 */
	public static <T extends Enum<T>> List<T> getList(Class<T> clazz, String regex, String method, String val) {
		if(StringUtils.isEmpty(method) || StringUtils.isEmpty(val)){
			return null;
		}
		List<T> list = new ArrayList<>();
		try {
			Method targetMethod = clazz.getDeclaredMethod(method);
			if(targetMethod == null){
				return null;
			}
			
			T[] enums = clazz.getEnumConstants();
			for (T t : enums) {
				if (Pattern.matches(regex, t.name()) && val.toString().equals(targetMethod.invoke(t).toString())) {
					list.add(t);
				}
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		} 
		return list;
	};

	public static <T extends Enum<T>> List<T> getList(Class<T> clazz, String regex){
		List<T> list = new ArrayList<>();
		try {
			T[] enums = clazz.getEnumConstants();
			for (T t : enums) {
				if (Pattern.matches(regex, t.name())) {
					list.add(t);
				}
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}
		return list;
	}
	
	public static void main(String[] args) {
		System.out.println(EnumHelperUtil.getOne(MediaRankEnum.class, "getCode", "0").getName());
		System.out.println(EnumHelperUtil.getOneByCode(MediaRankEnum.class, "2").getName());
		System.out.println(EnumHelperUtil.getByName(MediaRankEnum.class, "YIXIAN").getName());
	}
}
