/* Introduction a l'informatique II (ITI 1521)
 * Introduction to Computing II (ITI 1121)
 */

/**
 * 
 * @author Marcel Turcotte, Universite d'Ottawa/University of Ottawa
 */

import java.net.MalformedURLException;
import java.io.IOException;

public class Crawler {

	// i) if the URL is valid no exception will be thrown, ii) since
	// the method catches the exceptions, there is no need to declare
	// them.  
	// Note: the two catch statements could be replaced with one
	// 'catch ( IOException e )' since MalformedURLException is a
	// subclass of IOException; do you understand why?

	private static boolean isValid( String url ) {

		boolean isValid = false;

		try {
			new HTML( url );
			isValid = true;
		} catch ( MalformedURLException e ) {
			isValid = false; // isValid is alredy false ...
		} catch ( IOException e ) {
			isValid = false;
		}

		return isValid;
	}

	// i) implements the breath-first search algorithm seen in class
	// ii) IOException must be declared because this is a checked exception,
	// however, this exception should never be thrown since the URL
	// are first verified by isValid.
	// iii) solutions only contain valid solutions
	// iv) solutions becomes empty if there are no path going
	// from in to out

	private static Path solve( String in, String out ) throws MalformedURLException, IOException {

		// pre-conditions

		if ( ( ! isValid( in ) ) || ( ! isValid( out ) ) ) {
			return null;
		}

		Queue<Path> solutions = new LinkedQueue<Path>();
		Path solution = new Path( null, in );
		solutions.enqueue( solution );
		boolean found = in.equals( out ); // trivial case

		while ( ( ! found ) && ( ! solutions.isEmpty() ) ) {

			solution = solutions.dequeue();

			System.out.println( "visiting " + solution.getLastURL() );

			HTML page = new HTML( solution.getLastURL() );

			while ( ( ! found ) && page.hasMoreURLs() ) { // considering all neighboring pages
				String url = page.nextURL();
				if ( isValid( url ) && ( ! solution.contains( url ) ) ) {
					Path newPath = new Path( solution, url );
					if ( url.equals( out ) ) {
						found = true;
						solution = newPath;
					} else {
						solutions.enqueue( newPath );
					}
				}
			}
		}

		if ( ! found ) {
			solution = null;
		}

		return solution;
	}

	public static void main( String[] args ) throws MalformedURLException, IOException {
		if ( args.length == 2 ) {
			Path s = solve( args[ 0 ], args[ 1 ] );
			if ( s == null ) {
				System.out.println( "no path" );
			} else {
				System.out.println( "solution:" );
				System.out.println( s );
			}
		} else {
			System.out.println( "Usage: java Crawler in out" );
		}
	}
}
