// ServicesTest.java
//
// Created: February 2008
//
// Copyright 2008 Martin Senger
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

package org.biomoby.service;

import org.biomoby.shared.parser.MobyPackage;
import org.biomoby.shared.parser.MobyJob;
import org.biomoby.shared.MobyException;
import org.biomoby.shared.MobyService;
import org.biomoby.shared.datatypes.*;
import org.biomoby.client.BaseCmdLineClient;
import org.biomoby.client.ExtendedProtocolClient;
import org.biomoby.client.MobyServiceLocator;
import org.biomoby.client.ExtendedServiceLocator;

import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;

import org.apache.commons.io.IOUtils;
import org.apache.commons.io.FileUtils;

import org.biomoby.service.dashboard.SimpleAnt;
//import org.biomoby.service.dashboard.ExitSecurityManager;

import org.apache.tools.ant.BuildException;
//import org.apache.tools.ant.ExitException;
import org.apache.tools.ant.NoBannerLogger;

import java.util.Properties;
import java.io.InputStream;
import java.io.IOException;
import java.io.File;
import java.util.Map;
import java.util.HashMap;


public class ServicesTest {

    private static final String INPUT_CS  = "src/test/junit-resources/ConcatSequences-input.xml";
    private static final String INPUT_CSS = "src/test/junit-resources/ConcatSequenceSet-input.xml";
 
    /**************************************************************************
     *
     *                              Set-Up
     *
     **************************************************************************/
    @BeforeClass
    public static void prepareSkeletons()
	throws BuildException {

 	Properties props = new Properties();

	props.put ("registry.cache.dir", "myCache");
	props.put ("moses.nographs", "true");
	props.put ("moses.authority", "samples.jmoby.net");
	props.put ("moses.quiet", "true");

	SimpleAnt ant = new SimpleAnt();
	NoBannerLogger logger = new NoBannerLogger();
	logger.setOutputPrintStream (System.out);
	logger.setErrorPrintStream (System.err);
 	ant.addBuildListener (logger);
 	ant.startAnt (new String[] { "samples" }, props);

    }

    /**************************************************************************
     *
     *                              Tests
     *
     **************************************************************************/

    /**************************************************************************
     * Calling a sample service (using a local class) by extending
     * BaseCmdLineClient and feeding there data from a pre-prepared
     * XML input.
     **************************************************************************/
    @Test
    public void callConcatSequences()
	throws IOException, MobyException {

	String[] args = new String[] {
	    "-class",   "org.jmoby.tutorial.service.ConcatSequencesImpl",
	    "-service", "ConcatSequences",
	    "-xml",     INPUT_CS,
	    "-noout"
	};
	new ConcatSequencesClient (args).doEverything();

    }

    private class ConcatSequencesClient
	extends BaseCmdLineClient {

	/*********************************************************************
	 * Constructor. Pass everything to the parent.
	 *********************************************************************/
	public ConcatSequencesClient (String[] args) {
	    super (args);
	}

	/*********************************************************************
	 * Here test the results.
	 *********************************************************************/
	public boolean useResponse (MobyJob response,
				    MobyPackage responseContext)
	    throws MobyException {

	    GenericSequence data = (GenericSequence)response.getData();
	    assertEquals ("tatatatatagctatagcgc", data.get_SequenceString());
	    assertEquals (20, data.getMoby_Length().getIntValue());
	    return true;
	}
    }

	
    /**************************************************************************
     * Calling a sample service (using a local class) by extending
     * ExtendedProtocolClient and feeding there data from a
     * pre-prepared XML input.
     **************************************************************************/
    @Test
    public void callConcatSequenceSet()
	throws IOException, MobyException {
	new ConcatSequenceSetClient().process();
    }

    private class ConcatSequenceSetClient
	extends ExtendedProtocolClient {

	//
	public MobyServiceLocator getServiceLocator()
	    throws MobyException {
	    ExtendedServiceLocator locator = new ExtendedServiceLocator
		(new MobyService ("ConcatSequenceSet"));
	    locator.setLocalClass ("org.jmoby.tutorial.service.ConcatSequenceSetImpl");
	    return locator;
	}

	//
	public boolean fillRequest (MobyJob request,
				    MobyPackage inputContext)
	    throws MobyException { return true;	}
	public String fillRequest()
	    throws MobyException {
	    try {
		return FileUtils.readFileToString (new File (INPUT_CSS));
	    } catch (IOException e) {
		throw new MobyException (e.toString());
	    }
	}

	//
	public boolean useResponse (MobyJob response,
				    MobyPackage responseContext)
	    throws MobyException {

	    GenericSequence data = (GenericSequence)response.getData();
	    assertEquals ("", data.get_SequenceString());
	    assertEquals (20, data.getMoby_Length().getIntValue());
	    return true;
	}
    }


    /**************************************************************************
     *
     *                            Optional parts
     *
     **************************************************************************/

    /**************************************************************************
     * This is to be able to run this JUnit 4 tests with a JUnit 3.x runner.
     **************************************************************************/
    public static junit.framework.Test suite() {
        return new junit.framework.JUnit4TestAdapter (getThisClass());
    }

    /**************************************************************************
     * Run tests from the command line.
     **************************************************************************/
    public static void main (String args[]) {
	org.junit.runner.JUnitCore.main (getThisClassName());
    }

    /**************************************************************************
     * Get the class (name) of this class (note that this is a static
     * method). This madness is here just because I do not want to
     * change the class name in the optional methods above when I copy
     * and paste this into a new test file.
     **************************************************************************/
    private static String getThisClassName() {
	Exception e = new Exception();
	StackTraceElement[] sTrace = e.getStackTrace();
	// sTrace[0] will be always there
	return sTrace[0].getClassName();
    }

    private static Class getThisClass() {
	try {
	    return org.apache.commons.lang.ClassUtils.getClass (getThisClassName());
	} catch (ClassNotFoundException e) {
	    System.err.println ("Cannot get class name.");
	    return java.lang.Object.class;
	}
    }

}
