package com.zjrs.appcomm.template.excel.mapper;

import com.zjrs.appcomm.template.excel.exception.IllegalHeaderException;
import org.springframework.util.StringUtils;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * Excel动态表头Mapper
 * @author froms
 *
 */
public class DynamicHeaderMapper implements StringHeaderMapper {

	/** 表头名与字段名的映射Mapper（key为Excel中表头名，value为字段field名） */
	private Map<String, String> fieldsMapper;
	public Map<String, String> getFieldsMapper() { return fieldsMapper; }
	public void setFieldsMapper(Map<String, String> fieldsMapper) { this.fieldsMapper = fieldsMapper; }

	/** 是否忽略Excel中缺少的表头 */
	private boolean ignoreLessHeaders;
	public boolean isIgnoreLessHeaders() { return ignoreLessHeaders; }
	public void setIgnoreLessHeaders(boolean ignoreLessHeaders) { this.ignoreLessHeaders = ignoreLessHeaders; }

	/** 是否忽略Excel中多出的表头 */
	private boolean ignoreMoreHeaders;
	public boolean isIgnoreMoreHeaders() { return ignoreMoreHeaders; }
	public void setIgnoreMoreHeaders(boolean ignoreMoreHeaders) { this.ignoreMoreHeaders = ignoreMoreHeaders; }

	/**
	 * Excel动态表头Mapper（默认校验多出的表头，忽略缺少的表头）
	 * @param fieldsMapper 表头名与字段名的映射Mapper（key为Excel中表头名，value为字段field名）
	 */
	public DynamicHeaderMapper(Map<String, String> fieldsMapper) {
		this(fieldsMapper, true, false);
	}
	
	/**
	 * Excel动态表头Mapper（可配置是否校验表头）
	 * @param fieldsMapper 表头名与字段名的映射Mapper（key为Excel中表头名，value为字段field名）
	 * @param ignoreLessHeaders 是否忽略Excel中缺少的表头
	 * @param ignoreMoreHeaders 是否忽略Excel中多出的表头
	 */
	public DynamicHeaderMapper(Map<String, String> fieldsMapper, boolean ignoreLessHeaders, boolean ignoreMoreHeaders) {
		this.fieldsMapper = fieldsMapper;
		this.ignoreLessHeaders = ignoreLessHeaders;
		this.ignoreMoreHeaders = ignoreMoreHeaders;
	}
	
	@Override
	public String[] mapper(String[] headers) throws IllegalHeaderException {
		Map<String, String> tFieldsMapper = new HashMap<String, String>(fieldsMapper);
		
		String[] fields = new String[headers.length];
		for (int i = 0; i < headers.length; i++) {
			String header = headers[i];
			if (StringUtils.isEmpty(header)) {
				continue;
			}
			String field = tFieldsMapper.remove(header);
			if (StringUtils.isEmpty(field)) {
				if (ignoreMoreHeaders) {
					throw new IllegalHeaderException(headers);
				}
				continue;
			}
			fields[i] = field;
		}
		
		if (ignoreLessHeaders) {
			Set<String> headersLess = tFieldsMapper.keySet();
			for (String header: headersLess) {
				if (!StringUtils.isEmpty(header)) {
					throw new IllegalHeaderException(headers);
				}
			}
		}
		
		int realFieldLength = fields.length;
		for (; realFieldLength >= 0; realFieldLength--) {
			if (!StringUtils.isEmpty(fields[realFieldLength - 1])) {
				break;
			}
		}
		if (realFieldLength == fields.length) {
			return fields;
		} else {
			return Arrays.copyOfRange(fields, 0, realFieldLength);
		}
	}
}
