package org.biomoby.shared.test;

import org.biomoby.shared.LSIDResolver;

import junit.framework.*;

import java.net.URL;

public class LSIDResolverTestCase extends TestCase{
    private final static String BIOMOBY_LSID = "urn:lsid:biomoby.org:servicetype:Retrieval:2001-09-21T16-00-00Z";
    private final static String BIOMOBY_LSID_VERSIONLESS = "urn:lsid:biomoby.org:servicetype:Retrieval";
    private final static String BIOMOBY_LSID_INVALID = "urn:lsid:biomoby.org:objectclass:TestNameThatDoesntReallyExist:2";
    private final static String UBIO_LSID_VERSIONLESS = "urn:lsid:ubio.org:classificationbank:1164063";
    private final static String MALFORMED_LSID = "urn:lsid:ubio.orgclassificationbank:1164063";
    private final static String UNRESOLVABLE_LSID = "urn:lsid:foo.bar:baz:qux";

    public LSIDResolverTestCase(String name){
	super(name);
    }

    public void testMetadataResolutionHTTP(){
	LSIDResolver resolver = new LSIDResolver();
	
	URL u = null;
	try{
	    u = resolver.resolveMetadataURL(BIOMOBY_LSID);
	} catch(Exception e){
	    e.printStackTrace();
	    fail(e.getClass().getName() + " while trying to resolve metadata for LSID " + BIOMOBY_LSID);
	}
	assertNotNull("Metadata URL returned by resolver was null for LSID " + BIOMOBY_LSID, u);
	try{
	    u.openStream();
	} catch(Exception e){
	    e.printStackTrace();
	    fail(e.getClass().getName() + " while trying to access the URL (" + 
		 u + ") resolved for the metadata of LSID " + BIOMOBY_LSID);
	}
    }
    
    public void testMetadataNonResolutionHTTP(){
	LSIDResolver resolver = new LSIDResolver();
	
	URL u = null;
	boolean failed = false;
	try{
	    u = resolver.resolveMetadataURL(UNRESOLVABLE_LSID);
	} catch(Exception e){
	    failed = true;
	}
	assertTrue("Metadata resolution did not throw an exception for an LSID " +
		   "whose authority should NOT be resolvable (" + UNRESOLVABLE_LSID + ")", failed);
    }

    // The Moby LSID server unfortunately responds to getAvailableServices for non-existent LSIDs
    // so we can't run this test at the moment...
    public void testMetadataInvalidResolutionHTTP(){
	LSIDResolver resolver = new LSIDResolver();
	
	URL u = null;
	try{
	    u = resolver.resolveMetadataURL(BIOMOBY_LSID_INVALID);
	} catch(Exception e){
	    fail(e.getClass().getName() + " while resolving an invalid (but well-formed) " +
		 "BioMOBY LSID (" + BIOMOBY_LSID_INVALID + "). It should have just returned null.");
	}
	assertNull("Metadata resolution returned a non-null URL (" + u + 
		   " even though the nonsense LSID should not resolve to " +
		   "real metadata (" + BIOMOBY_LSID_INVALID + ")", u);
    }

    public void testMetadataVersionlessResolutionHTTP(){
	LSIDResolver resolver = new LSIDResolver();
	
	URL u = null;
	try{
	    u = resolver.resolveMetadataURL(BIOMOBY_LSID_VERSIONLESS);
	} catch(Exception e){
	    e.printStackTrace();
	    fail(e.getClass().getName() + " while trying to resolve metadata for LSID " + BIOMOBY_LSID_VERSIONLESS);
	}
	assertNotNull("Metadata URL returned by resolver was null for LSID " + BIOMOBY_LSID_VERSIONLESS, u);
	try{
	    u.openStream();
	} catch(Exception e){
	    e.printStackTrace();
	    fail(e.getClass().getName() + " while trying to access the URL (" + 
		 u + ") resolved for the metadata of LSID " + BIOMOBY_LSID_VERSIONLESS);
	}

	try{
	    u = resolver.resolveMetadataURL(UBIO_LSID_VERSIONLESS);
	} catch(Exception e){
	    e.printStackTrace();
	    fail(e.getClass().getName() + " while trying to resolve metadata for LSID " + UBIO_LSID_VERSIONLESS);
	}
	assertNotNull("Metadata URL returned by resolver was null for LSID " + UBIO_LSID_VERSIONLESS, u);
	try{
	    u.openStream();
	} catch(Exception e){
	    e.printStackTrace();
	    fail(e.getClass().getName() + " while trying to access the URL (" + 
		 u + ") resolved for the metadata of LSID " + UBIO_LSID_VERSIONLESS);
	}	
    }

    public void testDataResolutionHTTP(){
	// TODO: find one that works
    }

    public void testDataVersionlessResolutionHTTP(){
	LSIDResolver resolver = new LSIDResolver();

	URL u = null;
	try{
	    u = resolver.resolveDataURL(UBIO_LSID_VERSIONLESS);
	} catch(Exception e){
	    e.printStackTrace();
	    fail(e.getClass().getName() + " while trying to resolve data for LSID " + UBIO_LSID_VERSIONLESS);
	}
	assertNotNull("Data URL returned by resolver was null for LSID " + UBIO_LSID_VERSIONLESS, u);
	try{
	    u.openStream();
	} catch(Exception e){
	    e.printStackTrace();
	    fail(e.getClass().getName() + " while trying to access the URL (" + 
		 u + ") resolved for the data of LSID " + UBIO_LSID_VERSIONLESS);
	}
    }

    public void testLSIDParsing(){
	LSIDResolver resolver = new LSIDResolver();
	
	URL u = null;
	boolean failed = false;
	try{
	    u = resolver.resolveMetadataURL(MALFORMED_LSID);
	} catch(Exception e){
	    failed = true;
	}
	assertTrue("Metadata resolution did not throw an exception " +
		   "as expected when given a malformed LSID", failed);
    }

    /**
     * @return a test suite for all the test methods of this test case.
     */
    public static Test suite() {

	TestSuite suite = new TestSuite();
 	suite.addTest(new LSIDResolverTestCase("testMetadataResolutionHTTP"));
 	suite.addTest(new LSIDResolverTestCase("testMetadataVersionlessResolutionHTTP"));
 	//suite.addTest(new LSIDResolverTestCase("testMetadataInvalidResolutionHTTP"));
 	suite.addTest(new LSIDResolverTestCase("testMetadataNonResolutionHTTP"));
 	suite.addTest(new LSIDResolverTestCase("testDataResolutionHTTP"));
 	suite.addTest(new LSIDResolverTestCase("testDataVersionlessResolutionHTTP"));
 	suite.addTest(new LSIDResolverTestCase("testLSIDParsing"));
        return suite;
    }

    public static void main(String[] args){
	junit.textui.TestRunner.run(suite());
    }
}
