package com.shin1ogawa;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

import com.google.appengine.api.urlfetch.URLFetchServicePb.URLFetchRequest;
import com.google.appengine.api.urlfetch.URLFetchServicePb.URLFetchResponse;
import com.google.appengine.tools.development.ApiProxyLocal;
import com.google.appengine.tools.development.ApiProxyLocalImpl;
import com.google.appengine.tools.development.LocalRpcService;
import com.google.apphosting.api.ApiProxy.ApiProxyException;
import com.google.apphosting.api.ApiProxy.Environment;
import com.google.apphosting.api.ApiProxy.LogRecord;
import com.shin1ogawa.servicemock.UrlFetchServiceMock;

/**
 * テスト時に使用する{@link ApiProxyLocal}の実装クラス。
 * @author shin1ogawa
 */
public class ApiProxyLocalMock implements ApiProxyLocal {

	private final ApiProxyLocal delegate;

	private final Map<String, LocalRpcService> serviceMocks = new HashMap<String, LocalRpcService>(
			5);

	public ApiProxyLocalMock(File appDir) {
		delegate = new ApiProxyLocalImpl(appDir) {
		};
	}

	/**
	 * 各種サービスのMockを登録する。
	 * @param serviceMock
	 */
	public void addServiceMock(LocalRpcService serviceMock) {
		serviceMocks.put(serviceMock.getPackage(), serviceMock);
	}

	public LocalRpcService getService(String arg0) {
		return delegate.getService(arg0);
	}

	public void setProperties(Map<String, String> arg0) {
		delegate.setProperties(arg0);
	}

	public void setProperty(String arg0, String arg1) {
		delegate.setProperty(arg0, arg1);
	}

	public void stop() {
		delegate.stop();
	}

	@SuppressWarnings("unchecked")
	public void log(Environment arg0, LogRecord arg1) {
		delegate.log(arg0, arg1);
	}

	@SuppressWarnings("unchecked")
	public byte[] makeSyncCall(Environment arg0, String packageName,
			String methodName, byte[] requestBytes) throws ApiProxyException {
		LocalRpcService localRpcService = serviceMocks.get(packageName);
		// とりあえずURLFetchServiceだけに対応。
		if (localRpcService != null
				&& localRpcService instanceof UrlFetchServiceMock
				&& methodName.equalsIgnoreCase("Fetch")) {
			UrlFetchServiceMock urlFetchServiceMock = (UrlFetchServiceMock) localRpcService;
			URLFetchRequest fetchRequest = new URLFetchRequest();
			fetchRequest.parseFrom(requestBytes);
			URLFetchResponse fetchResponse = urlFetchServiceMock.fetch(
					new LocalRpcService.Status(), fetchRequest);
			return fetchResponse.toByteArray();
		}
		return delegate.makeSyncCall(arg0, packageName, methodName,
				requestBytes);
	}
}
