// MabuhayImpl.java
//
//    Created: August 2005
//
// This file is a component of the BioMoby project.
// Copyright Martin Senger (martin.senger@gmail.com).
//

package org.jmoby.tutorial.service;

import net.jmoby.samples.MabuhaySkel;
import org.biomoby.shared.MobyException;
import org.biomoby.shared.parser.MobyPackage;
import org.biomoby.shared.parser.MobyJob;
import org.biomoby.shared.datatypes.*;

import java.net.URL;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.regex.PatternSyntaxException;
import java.util.Vector;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;

/**
 * The second example of a BioMoby service. <p>
 *
 * This service accepts a regular expression containing name of a
 * language (or names of languages), and returns a Hello (or Hellos)
 * in those languages. The main purpose is to show how to deal with
 * non-primitive data types - <tt>Regex</tt> as input and a collection
 * of <tt>simple_key_value_pair</tt>s as output. <p>
 *
 * The details about service are in the generated sketeton
 * <tt>MabuhaySkel</tt>. <p>
 *
 * @author <A HREF="mailto:martin.senger@gmail.com">Martin Senger</A>
 * @version $Id: MabuhayImpl.java,v 1.2 2008/03/02 12:45:26 senger Exp $
 */

public class MabuhayImpl
    extends MabuhaySkel {

    String[] languages = new String[] {};
    String[] hellos = new String[] {};

    /**************************************************************************
     * This is a mandatory method to be implemented.
     *************************************************************************/
    public void processIt (MobyJob request,
			   MobyJob response,
			   MobyPackage outputContext)
	throws MobyException {
 	Regex input = get_language (request);
	if (input == null) return;

 	simple_key_value_pair[] output = doBusiness (input);
 	set_helloSet (response, output) ;
    }

    /**************************************************************************
     * Here is where the bussines logic is done
     *************************************************************************/
    protected simple_key_value_pair[] doBusiness (Regex regex)
	throws MobyException {

	String regExpression = regex.get_regex();
	if (isEmpty (regExpression))
	    return new simple_key_value_pair[] {};

	synchronized (languages) {
	    if (languages.length == 0)
		readHellos();
	}

	// compile a regex pattern according to the client input
	Pattern pattern = null;
	int flags = 0;
	if (regex.is_case_insensitive()) flags |= Pattern.CASE_INSENSITIVE;
	if (regex.is_dotall_mode())      flags |= Pattern.DOTALL;
	if (regex.is_multiline_mode())   flags |= Pattern.MULTILINE;
// 	if (regex.is_literal_mode())     flags |= Pattern.LITERAL;   // for Java 1.5 ?

	try {
 	    pattern = Pattern.compile (regExpression, flags);
	} catch (PatternSyntaxException e) {
	    throw new MobyException ("Regular expression '" + regex.get_regex() +
				     "' is invalid. " + e.getMessage());
	} catch (IllegalArgumentException e) {
	    throw new MobyException ("Developer's problem: " + e.toString());
	}

	// match pattern against all possible values we have
	Vector<simple_key_value_pair> v = new Vector<simple_key_value_pair>();
	Matcher matcher = pattern.matcher ("");
	for (int i = 0; i < languages.length; i++) {
 	    matcher.reset (languages[i]);
	    if (matcher.find()) {
		simple_key_value_pair pair = new simple_key_value_pair();
		pair.set_key (languages[i]);
		pair.set_the_value (hellos[i]);
		v.addElement (pair);
	    }
	}

	// send result back
	simple_key_value_pair[] result = new simple_key_value_pair [v.size()];
	v.copyInto (result);
	return result;
    }

    /**************************************************************************
     * Read a list of "Hellos" from an external file and stores it in
     * instance variables 'hellos' and 'languages' (both have the same
     * length).
     *************************************************************************/
    protected void readHellos()
	throws MobyException {

	InputStream ins =
	    this.getClass().getClassLoader().getResourceAsStream
	    ("resources/mabuhay.file");
	if (ins != null) {
	    try {
		Vector<String> l = new Vector<String> (3000);
		Vector<String> h = new Vector<String> (3000);
		BufferedReader data = new BufferedReader (new InputStreamReader (ins));
		String line;
		while ((line = data.readLine()) != null) {
		    String[] parts = line.split ("\t", 2);
		    if (parts.length > 1) {
			l.addElement (parts[0]);
			h.addElement (parts[1]);
		    }
		}
		data.close();
		languages = new String [l.size()];
		l.copyInto (languages);
		hellos = new String [h.size()];
		h.copyInto (hellos);

	    } catch (IOException e) {
		throw new MobyException ("ERROR: " + e.toString());
	    }
	}
    }

}

