package com.xunhong.erp.turbo.web.interceptor;

import com.xunhong.erp.turbo.web.annotation.CacheControl;
import com.xunhong.erp.turbo.web.enums.CachePolicy;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;

public class CacheControlHandlerInterceptor implements HandlerInterceptor {
	private static final String HEADER_EXPIRES = "Expires";
	private static final String HEADER_CACHE_CONTROL = "Cache-Control";
	private boolean useExpiresHeader = true;

	public CacheControlHandlerInterceptor() {
	}

	protected final void assignCacheControlHeader(HttpServletRequest request, HttpServletResponse response, Object handler) {
		CacheControl cacheControl = this.getCacheControl(request, response, handler);
		String cacheControlHeader = this.createCacheControlHeader(cacheControl);
		if (cacheControlHeader != null) {
			response.setHeader("Cache-Control", cacheControlHeader);
			if (this.useExpiresHeader) {
				response.setDateHeader("Expires", this.createExpiresHeader(cacheControl));
			}
		}

	}

	protected final String createCacheControlHeader(CacheControl cacheControl) {
		StringBuilder builder = new StringBuilder();
		if (cacheControl == null) {
			return null;
		} else {
			CachePolicy[] policies = cacheControl.policy();
			if (cacheControl.maxAge() >= 0) {
				builder.append("max-age=").append(cacheControl.maxAge());
			}

			if (cacheControl.sharedMaxAge() >= 0) {
				if (builder.length() > 0) {
					builder.append(", ");
				}

				builder.append("s-maxage=").append(cacheControl.sharedMaxAge());
			}

			if (policies != null) {
				CachePolicy[] arr$ = policies;
				int len$ = policies.length;

				for (int i$ = 0; i$ < len$; ++i$) {
					CachePolicy policy = arr$[i$];
					if (builder.length() > 0) {
						builder.append(", ");
					}

					builder.append(policy.policy());
				}
			}

			return builder.length() > 0 ? builder.toString() : null;
		}
	}

	protected final long createExpiresHeader(CacheControl cacheControl) {
		Calendar expires = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
		if (cacheControl.maxAge() >= 0) {
			expires.add(13, cacheControl.maxAge());
		}

		return expires.getTime().getTime();
	}

	protected final CacheControl getCacheControl(HttpServletRequest request, HttpServletResponse response, Object handler) {
		if (handler != null && handler instanceof HandlerMethod) {
			HandlerMethod handlerMethod = (HandlerMethod) handler;
			CacheControl cacheControl = (CacheControl) handlerMethod.getMethodAnnotation(CacheControl.class);
			return cacheControl == null ? (CacheControl) handlerMethod.getBeanType().getAnnotation(CacheControl.class) : cacheControl;
		} else {
			return null;
		}
	}

	public final boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		this.assignCacheControlHeader(request, response, handler);

		return true;
	}

	public final void setUseExpiresHeader(boolean useExpiresHeader) {
		this.useExpiresHeader = useExpiresHeader;
	}
}
