package cn.wise.sc.cement.business.config;

import cn.wise.sc.cement.business.exception.BusinessOldException;
import cn.wise.sc.cement.business.wrapper.WrapMapper;
import cn.wise.sc.cement.business.wrapper.Wrapper;
import org.springframework.boot.autoconfigure.web.servlet.error.AbstractErrorController;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.context.request.WebRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

@ControllerAdvice
@RestController
public class GlobalDefaultExceptionHandler extends AbstractErrorController {

	@ExceptionHandler(value = RuntimeException.class)
	@ResponseBody
	public Wrapper defaultErrorHandler(HttpServletResponse response, BusinessOldException e) {
		response.setStatus(e.getStatusCode().value());
		return WrapMapper.error(e.getMessage());
	}

	public GlobalDefaultExceptionHandler(ErrorAttributes errorAttributes) {
		super(errorAttributes);
	}

	private static final String ERROR_PATH = "/error";

	@Override
	public String getErrorPath() {
		return ERROR_PATH;
	}

	@RequestMapping(value = ERROR_PATH)
	public Wrapper error(HttpServletRequest request) {
		WebRequest webRequest = new ServletWebRequest(request);
		Throwable e = getError(webRequest);
		if (e == null) {
			Map<String, Object> attributes = getErrorAttributes(request, false);
			Object timestamp = attributes.get("timestamp");
			Object status = attributes.get("status");
			String error = attributes.get("error").toString();
			String message = attributes.get("message").toString();
			Object path = attributes.get("path");
			//todo 上线后更改为error
			return WrapMapper.wrap(Integer.parseInt(status.toString()), message);
		} else {
			return WrapMapper.error(e.getMessage());
		}
	}

	private Throwable getError(WebRequest webRequest) {
		return (Throwable) this.getAttribute(webRequest, "javax.servlet.error.exception");
	}

	private Object getAttribute(RequestAttributes requestAttributes, String name) {
		return requestAttributes.getAttribute(name, 0);
	}
}