/*
 * Copyright 2004-2005 the original author or authors.
 * 
 * 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.codehaus.groovy.grails.commons;

import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyResourceLoader;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;
import org.codehaus.groovy.control.CompilationFailedException;
import org.codehaus.groovy.grails.exceptions.MoreThanOneActiveDataSourceException;
import org.springframework.core.io.Resource;

/**
 * 
 * 
 * @author Steven Devijver
 * @since Jul 2, 2005
 */
public class DefaultGrailsApplication implements GrailsApplication {

	private GroovyClassLoader cl = null;
	private GrailsControllerClass[] controllerClasses = null;
	private GrailsPageFlowClass[] pageFlows = null;
	private GrailsDomainClass[] domainClasses = null;
	private GrailsDataSource dataSource = null;
	private GrailsServiceClass[] services = null;
	private GrailsBootstrapClass[] bootstrapClasses = null;
	
	private Map controllerMap = null;
	private Map domainMap = null;
	private Map pageFlowMap = null;
	private Map serviceMap = null;
	private Map bootstrapMap = null;
	
	private Class[] allClasses = null;
	
	
	private static Logger log = Logger.getLogger(DefaultGrailsApplication.class);
	
	public DefaultGrailsApplication(final Class[] classes, GroovyClassLoader classLoader) {
		if(classes == null)
			throw new IllegalArgumentException("Constructor argument 'classes' cannot be null");
		
		configureLoadedClasses(classes);
		this.cl = classLoader;
	}
	public DefaultGrailsApplication(final Resource[] resources) throws IOException, ClassNotFoundException {
		super();
		
		log.debug("Loading Grails application.");

		final Collection loadedResources = new ArrayList();
		
		GroovyResourceLoader resourceLoader = new GroovyResourceLoader() {
			public File loadGroovyFile(String resource) {
				String filename = resource.replace('.', '/') + ".groovy";
				Resource foundResource = null;
				for (int i = 0; resources != null && i < resources.length; i++) {
					if (resources[i].getFilename().endsWith(filename)) {
						if (foundResource == null) {
							foundResource = resources[i];
						} else {
							throw new IllegalArgumentException("Resources [" + resources[i].getFilename() + "] and [" + foundResource.getFilename() + "] end with [" + filename + "]. Cannot load because of duplicate match!");
						}
					}
				}
				try {
					if (foundResource != null) {
						loadedResources.add(foundResource);
						return foundResource.getFile();
					} else {
						return null;
					}
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
			}
		};
		this.cl = new GroovyClassLoader();
		this.cl.setResourceLoader(resourceLoader);
		for (int i = 0; resources != null && i < resources.length; i++) {
			try {
				log.debug("Loading groovy file :[" + resources[i].getFile().getAbsolutePath() + "]");
				if (!loadedResources.contains(resources[i])) {
					cl.parseClass(resources[i].getFile());
				}
			} catch (CompilationFailedException e) {
				throw new org.codehaus.groovy.grails.exceptions.CompilationFailedException("Compilation error in file [" + resources[i].getFilename() + "]: " + e.getMessage(), e);
			}
		}
		// get all the classes that were loaded
		Class[] classes = cl.getLoadedClasses();		
		this.allClasses = classes;
		
		configureLoadedClasses(classes);
	}

	private void configureLoadedClasses(Class[] classes) {
		
		// first load the domain classes
		this.domainMap = new HashMap();
		log.debug("Going to inspect domain classes.");
		for (int i = 0; i < classes.length; i++) {
			log.debug("Inspecting [" + classes[i].getName() + "]");
			if (Modifier.isAbstract(classes[i].getModifiers())) {
				log.debug("[" + classes[i].getName() + "] is abstract.");
				continue;
			}
			// check that it is a domain class
			if(GrailsClassUtils.isDomainClass(classes[i])) {
				log.debug("[" + classes[i].getName() + "] is a domain class.");
				GrailsDomainClass grailsDomainClass = new DefaultGrailsDomainClass(classes[i]);				
				this.domainMap.put(grailsDomainClass.getFullName(), grailsDomainClass);		
						
			} else {
				log.debug("[" + classes[i].getName() + "] is not a domain class.");
			}
		}		
		
		this.controllerMap = new HashMap();
		this.pageFlowMap = new HashMap();
		this.serviceMap = new HashMap();
		this.bootstrapMap = new HashMap();
		for (int i = 0; i < classes.length; i++) {
			if (Modifier.isAbstract(classes[i].getModifiers())) {
				continue;
			}
			if (GrailsClassUtils.isControllerClass(classes[i])  /* && not ends with FromController */) {
				GrailsControllerClass grailsControllerClass = new DefaultGrailsControllerClass(classes[i]);
				if (grailsControllerClass.getAvailable()) {
					this.controllerMap.put(grailsControllerClass.getFullName(), grailsControllerClass);
				}
			} else if (GrailsClassUtils.isPageFlowClass(classes[i])) {
				GrailsPageFlowClass grailsPageFlowClass = new DefaultGrailsPageFlowClass(classes[i]);
				if (grailsPageFlowClass.getAvailable()) {
					this.pageFlowMap.put(grailsPageFlowClass.getFullName(), grailsPageFlowClass);
				}
			} else if (GrailsClassUtils.isDataSource(classes[i])) {
				GrailsDataSource tmpDataSource = new DefaultGrailsDataSource(classes[i]);
				if (tmpDataSource.getAvailable()) {
					if (dataSource == null) {
						dataSource = tmpDataSource;
					} else {
						throw new MoreThanOneActiveDataSourceException("More than one active data source is configured!");
					}
				}
			} else if (GrailsClassUtils.isService(classes[i])) {
				GrailsServiceClass grailsServiceClass = new DefaultGrailsServiceClass(classes[i]);
				serviceMap.put(grailsServiceClass.getFullName(), grailsServiceClass);
			}
			else if(GrailsClassUtils.isBootstrapClass(classes[i])) {
				GrailsBootstrapClass grailsBootstrapClass = new DefaultGrailsBootstrapClass(classes[i]);
				this.bootstrapMap.put(grailsBootstrapClass.getFullName(),grailsBootstrapClass);
			}
		}
		
		this.controllerClasses = ((GrailsControllerClass[])controllerMap.values().toArray(new GrailsControllerClass[controllerMap.size()]));
		this.pageFlows = ((GrailsPageFlowClass[])pageFlowMap.values().toArray(new GrailsPageFlowClass[pageFlowMap.size()]));
		this.domainClasses = ((GrailsDomainClass[])this.domainMap.values().toArray(new GrailsDomainClass[domainMap.size()]));
		this.services = ((GrailsServiceClass[])this.serviceMap.values().toArray(new GrailsServiceClass[serviceMap.size()]));
		this.bootstrapClasses = ((GrailsBootstrapClass[])this.bootstrapMap.values().toArray(new GrailsBootstrapClass[bootstrapMap.size()]));
		
		configureDomainClassRelationships();	
	}
	/**
	 * Sets up the relationships between the domain classes, this has to be done after
	 * the intial creation to avoid looping
	 *
	 */
	private void configureDomainClassRelationships() {

		for (int i = 0; i < this.domainClasses.length; i++) {
			GrailsDomainClassProperty[] props = this.domainClasses[i].getPersistantProperties();
			
			for (int j = 0; j < props.length; j++) {
				if(props[j].isAssociation()) {
					DefaultGrailsDomainClassProperty prop = (DefaultGrailsDomainClassProperty)props[j];
					GrailsDomainClass referencedGrailsDomainClass = (GrailsDomainClass)this.domainMap.get( props[j].getReferencedPropertyType().getName() );
					prop.setReferencedDomainClass(referencedGrailsDomainClass);
					
				}
			}
						
		}
		
		for (int i = 0; i < this.domainClasses.length; i++) {
			GrailsDomainClassProperty[] props = this.domainClasses[i].getPersistantProperties();
			
			for (int j = 0; j < props.length; j++) {
				if(props[j].isAssociation()) {
					DefaultGrailsDomainClassProperty prop = (DefaultGrailsDomainClassProperty)props[j];
					GrailsDomainClassProperty[] referencedProperties =  prop.getReferencedDomainClass().getPersistantProperties();					
					for (int k = 0; k < referencedProperties.length; k++) {
						if(referencedProperties[k].getReferencedPropertyType().equals( this.domainClasses[i].getClazz())) {
							prop.setOtherSide(referencedProperties[k]);
							break;
						}
					}		
				}
			}
						
		}		
	
			
	}

	public GrailsControllerClass[] getControllers() {
		return this.controllerClasses;
	}

	public GrailsControllerClass getController(String name) {
		return (GrailsControllerClass)this.controllerMap.get(name);
	}
	
	public GrailsControllerClass getControllerByURI(String uri) {
		for (int i = 0; i < controllerClasses.length; i++) {
			if (controllerClasses[i].mapsToURI(uri)) {
				return controllerClasses[i];
			}
		}
		return null;
	}

	public GrailsPageFlowClass getPageFlow(String fullname) {
		return (GrailsPageFlowClass)this.pageFlowMap.get(fullname);
	}
	
	public GrailsPageFlowClass[] getPageFlows() {
		return this.pageFlows;
	}
	
	public GroovyClassLoader getClassLoader() {
		return this.cl;
	}

	public GrailsDomainClass[] getGrailsDomainClasses() {
		return this.domainClasses;
	}

	public GrailsDomainClass getGrailsDomainClass(String name) {
			return (GrailsDomainClass)this.domainMap.get(name);
	}
	

	public GrailsDataSource getGrailsDataSource() {
		return this.dataSource;
	}
	
	public GrailsServiceClass[] getGrailsServiceClasses() {
		return this.services;
	}
	
	public GrailsServiceClass getGrailsServiceClass(String name) {
		return (GrailsServiceClass)this.serviceMap.get(name);
	}
	
	public Class[] getAllClasses() {
		return this.allClasses;
	}

	public GrailsBootstrapClass[] getGrailsBootstrapClasses() {		// 
		return this.bootstrapClasses;
	}
	
}
