package net.razorvine.examples;

import java.io.IOException;
import java.util.SortedMap;

import net.razorvine.pyro.Config;
import net.razorvine.pyro.NameServerProxy;
import net.razorvine.pyro.PyroException;
import net.razorvine.pyro.PyroProxy;
import net.razorvine.pyro.PyroURI;

/**
 * Simple example that shows the use of Pyro with the Pyro echo server.
 *
 * @author Irmen de Jong (irmen@razorvine.net)
 */
public class EchoExample {

	public static void main(String[] args) throws IOException {

		System.out.println("Testing Pyro echo server (make sure it's running, with nameserver enabled)...");
		System.out.println("Pyrolite version: "+Config.PYROLITE_VERSION);

		setConfig();

		NameServerProxy ns = NameServerProxy.locateNS(null);
		PyroProxy p = new PyroProxy(ns.lookup("test.echoserver"));
		p.pyroHandshake = "banana";
		ns.close();

		// PyroProxy p=new PyroProxy("localhost",9999,"test.echoserver");

		Object x=42;
		System.out.println("echo param:");
		System.out.println(x);
		Object result=p.call("echo", x);
		System.out.println("return value:");
		System.out.println(result);

		String s="This string is way too long. This string is way too long. This string is way too long. This string is way too long. ";
		s=s+s+s+s+s;
		System.out.println("echo param:");
		System.out.println(s);
		result=p.call("echo", s);
		System.out.println("return value:");
		System.out.println(result);

		// echo a pyro proxy and validate that all relevant attributes are also present on the proxy we got back.
		System.out.println("proxy test.");
		result = p.call("echo", p);
		PyroProxy p2 = (PyroProxy) result;
		System.out.println("response proxy: " + p2);
		if(!p2.objectid.equals("test.echoserver")) throw new AssertionError("objectid");
		if(!((String)p2.pyroHandshake).equals("banana")) throw new AssertionError("handshake");
		if(!p2.pyroMethods.contains("echo")) throw new AssertionError("methods");

		System.out.println("remote iterator test.");
		@SuppressWarnings("unchecked")
		Iterable<String> iter = (Iterable<String>)p.call("generator");
		for(String item: iter) {
			System.out.println("  got item: "+item);
		}

		System.out.println("error test.");
		try {
			result=p.call("error");
		} catch (PyroException e) {
			System.out.println("Pyro Exception (expected)! "+e.getMessage());
			System.out.println("Pyro Exception cause: "+e.getCause());
			System.out.println("Pyro Exception remote traceback:\n>>>\n"+e._pyroTraceback+"<<<");
		}
		try {
			result=p.call("error_with_text");
		} catch (PyroException e) {
			System.out.println("Pyro Exception (expected)! "+e.getMessage());
			System.out.println("Pyro Exception cause: "+e.getCause());
			System.out.println("Pyro Exception remote traceback:\n>>>\n"+e._pyroTraceback+"<<<");
		}

//		System.out.println("shutting down the test echo server.");
//		p.call("shutdown");

		// tidy up:
		p.close();
	}

	static void setConfig() {
		String tracedir=System.getenv("PYRO_TRACE_DIR");
		if(System.getProperty("PYRO_TRACE_DIR")!=null) {
			tracedir=System.getProperty("PYRO_TRACE_DIR");
		}

		Config.MSG_TRACE_DIR=tracedir;
	}
}


/**
 * This custom proxy adds custom annotations to the pyro messages
 */
@SuppressWarnings("serial")
class CustomProxy extends PyroProxy
{
	public CustomProxy(PyroURI uri) throws IOException
	{
		super(uri);
	}
	@Override
	public SortedMap<String, byte[]> annotations()
	{
		SortedMap<String, byte[]> ann = super.annotations();
		ann.put("XYZZ", "A custom annotation!".getBytes());
		return ann;
	}
}
