/*
 * Copyright 2003-2007 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 groovy.lang;

import groovy.security.GroovyCodeSourcePermission;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.AccessController;
import java.security.CodeSource;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.security.cert.Certificate;

/**
 * CodeSource wrapper class that allows specific security policies to be associated with a class
 * compiled from groovy source.
 * 
 * @author Steve Goetze
 */
public class GroovyCodeSource {
	
	/** 
	 * The codeSource to be given the generated class.  This can be used by policy file
	 * grants to administer security.
	 */
	private CodeSource codeSource;
	/** The name given to the generated class */
	private String name;
	/** The groovy source to be compiled and turned into a class */
	private InputStream inputStream;
	/** The certificates used to sign the items from the codesource */
	Certificate[] certs;
    private boolean cachable;
    
	private File file;
	
	public GroovyCodeSource(String script, String name, String codeBase) {
		this(new ByteArrayInputStream(script.getBytes()), name, codeBase);
	}
	
	/**
	 * Construct a GroovyCodeSource for an inputStream of groovyCode that has an
	 * unknown provenance -- meaning it didn't come from a File or a URL (e.g. a String).
	 * The supplied codeBase will be used to construct a File URL that should match up
	 * with a java Policy entry that determines the grants to be associated with the
	 * class that will be built from the InputStream.
	 * 
	 * The permission groovy.security.GroovyCodeSourcePermission will be used to determine if the given codeBase
	 * may be specified.  That is, the current Policy set must have a GroovyCodeSourcePermission that implies
	 * the codeBase, or an exception will be thrown.  This is to prevent callers from hijacking
	 * existing codeBase policy entries unless explicitly authorized by the user.
	 */
	public GroovyCodeSource(InputStream inputStream, String name, String codeBase) {
		this.inputStream = inputStream;
		this.name = name;
		SecurityManager sm = System.getSecurityManager();
		if (sm != null) {
		    sm.checkPermission(new GroovyCodeSourcePermission(codeBase));
		}
		try {
			this.codeSource = new CodeSource(new URL("file", "", codeBase), (java.security.cert.Certificate[])null);
		} catch (MalformedURLException murle) {
			throw new RuntimeException("A CodeSource file URL cannot be constructed from the supplied codeBase: " + codeBase);
		}
	}
	
	public GroovyCodeSource(final File file) throws FileNotFoundException {
		if (!file.exists())
		    throw new FileNotFoundException(file.toString() + " (" +  file.getAbsolutePath() +  ")");
		else {
		   try {
		       if (!file.canRead())
		           throw new RuntimeException(file.toString() + " can not be read. Check the read permisson of the file \"" + file.toString() + "\" (" +  file.getAbsolutePath() +  ").");
		   }
		   catch (SecurityException e) {
		        throw e;
		    }
		}

		//this.inputStream = new FileInputStream(file);
		this.file = file;
		this.inputStream = null;
        this.cachable = true;
		//The calls below require access to user.dir - allow here since getName() and getCodeSource() are
		//package private and used only by the GroovyClassLoader.
		try {
            Object[] info = (Object[]) AccessController.doPrivileged( new PrivilegedExceptionAction() {
				public Object run() throws MalformedURLException {
                    Object[] info = new Object[2];
                    URL url = file.toURI().toURL();
                    info[0] = url.toExternalForm();
					//toURI().toURL() will encode, but toURL() will not.
					info[1] = new CodeSource(url, (Certificate[]) null);
                    return info;
				}
			});
			this.name = (String) info[0];
            this.codeSource = (CodeSource) info[1];
		} catch (PrivilegedActionException pae) {
			throw new RuntimeException("Could not construct a URL from: " + file);
		}
	}
	
	public GroovyCodeSource(URL url) throws IOException {
		if (url == null) {
			throw new RuntimeException("Could not construct a GroovyCodeSource from a null URL");
		}
		this.inputStream = url.openStream();
		this.name = url.toExternalForm();
		this.codeSource = new CodeSource(url, (java.security.cert.Certificate[])null);
	}
	
	CodeSource getCodeSource() {
		return codeSource;
	}

	public InputStream getInputStream() {
        if(this.inputStream != null) {
            return this.inputStream;
        }
        else {
            try {
                if (file!=null) return new FileInputStream(file);
            } catch (FileNotFoundException fnfe) {
                // IGNORE
            }
            return inputStream;            
        }
	}

	public String getName() {
		return name;
	}
    
    public File getFile() {
        return file;
    }
    
    public void setCachable(boolean b) {
        cachable = b;
    }

    public boolean isCachable() {
        return cachable;
    }
}
