package dareka.processor.impl;

import java.io.IOException;
import java.net.Socket;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import dareka.processor.HttpRequestHeader;
import dareka.processor.HttpResponseHeader;
import dareka.processor.Processor;
import dareka.processor.Resource;
import dareka.processor.StringResource;
import dareka.processor.URLResource;
import dareka.processor.util.GetThumbInfoUtil;

// getthumbinfoをメモリにキャッシュする
public class GetThumbInfoProcessor implements Processor {
	
	private static final String[] SUPPORTED_METHODS = new String[] { "GET" };
	private static final Pattern GETTHUMBINFO_URL_PATTERN = Pattern.compile(
			"^(http://ext\\.nicovideo\\.jp/api/getthumbinfo/)(\\w{2}\\d+)(\\?nlFilter)?([\\?&]\\d+)?$");
	
	public String[] getSupportedMethods() {
		return SUPPORTED_METHODS;
	}
	
	public Pattern getSupportedURLAsPattern() {
		return GETTHUMBINFO_URL_PATTERN;
	}
	
	public String getSupportedURLAsString() {
		return null;
	}
	
	protected void finalize() {
		// GCの時にでも全てのキャッシュをExpire処理してメモリを有効活用
		GetThumbInfoUtil.expires();
	}
	
	public Resource onRequest(HttpRequestHeader requestHeader, Socket browser)
			throws IOException {
		// Processorで受けるとRewriterが処理されなので自前で呼び出す
		RewriterProcessor rw = dareka.Main.getRewriterProcessor();
		String uri = requestHeader.getURI();
		Matcher m = GETTHUMBINFO_URL_PATTERN.matcher(uri);
		if (m.find()) {
			String smid = m.group(2);
			if (m.group(4) != null) {
				// 数字パラメータ付きならキャッシュを削除して再取得
				GetThumbInfoUtil.remove(smid);
			}
			URLResource r = GetThumbInfoUtil.getURLResource(smid);
			if (r != null) {
				HttpResponseHeader rh = r.getResponseHeader(null, null);
				if (rh.getStatusCode() != 200)
					return r; // 200以外ならRewriter処理せずそのまま返す
				byte[] original = r.getResponseBody();
				if (original != null && original.length > 0) {
					byte[] replaced = rw.contentRewriter(uri, original, requestHeader, rh);
					if (original != replaced) {
						return StringResource.getRawResource(rh, replaced);
					} else {
						// 書き換えられていなければURLResourceをそのまま返す
						return r;
					}
				}
			} else {
				// GetThumbInfoUtilで取得出来なければパラメータを除去して直接取得
				requestHeader.setURI(m.group(1) + m.group(2));
			}
		}
		return rw.onRequest(requestHeader, browser);
	}
	
}
