/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.apache.myfaces.extensions.scripting.loaders.java;

import org.apache.myfaces.extensions.scripting.core.util.ClassUtils;
import org.apache.myfaces.extensions.scripting.core.util.WeavingContext;
import org.apache.myfaces.extensions.scripting.monitor.ClassResource;
import org.apache.myfaces.extensions.scripting.monitor.RefreshAttribute;
import org.apache.myfaces.extensions.scripting.monitor.RefreshContext;

import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * A specialized non tainting classloader for our scanners
 */
@SuppressWarnings("unused")
public class ScannerClassloader extends ClassLoader {

    File _tempDir = null;

    Map<String, Class> _alreadyScanned = new HashMap<String, Class>();

    final Logger _logger = Logger.getLogger(ScannerClassloader.class.getName());


    public ScannerClassloader(ClassLoader classLoader, int scriptingEngine, String engineExtension, File tempDir) {
        super(classLoader);

        this._tempDir = tempDir;
    }

    @Override
    public InputStream getResourceAsStream(String name) {
        File resource = new File(_tempDir.getAbsolutePath() + File.separator + name);
        if (resource.exists()) {
            try {
                return new FileInputStream(resource);
            } catch (FileNotFoundException e) {
                return super.getResourceAsStream(name);
            }
        }
        return super.getResourceAsStream(name);
    }

    public File getClassFile(String className) {
        return ClassUtils.classNameToFile(_tempDir.getAbsolutePath(), className);
    }

    @Override
    public Class<?> loadClass(String className) throws ClassNotFoundException {
        //check if our class exists in the tempDir

        if (_alreadyScanned.containsKey(className)) {
            return _alreadyScanned.get(className);
        }

        File target = getClassFile(className);
        if (!target.exists()) {
            return super.loadClass(className);
        }

        ClassResource data = WeavingContext.getFileChangedDaemon().getClassMap().get(className);
        if (data != null && !data.getRefreshAttribute().requiresRefresh()) {
            return data.getAClass();
        }

        FileInputStream iStream = null;

        int fileLength;
        byte[] fileContent;
        try {
            //we cannot load while a compile is in progress
            //we have to wait until it is one
            synchronized (RefreshContext.COMPILE_SYNC_MONITOR) {
                fileLength = (int) target.length();
                fileContent = new byte[fileLength];
                iStream = new FileInputStream(target);
                int len = iStream.read(fileContent);
                if (_logger.isLoggable(Level.FINER)) {
                    _logger.log(Level.FINER, "class read {0}� bytes read", String.valueOf(len));
                }
            }

            //we have to do it here because just in case
            //a dependent class is loaded as well we run into classcast exceptions
            Class retVal = super.defineClass(className, fileContent, 0, fileLength);
            _alreadyScanned.put(className, retVal);
            return retVal;

        } catch (FileNotFoundException e) {
            throw new ClassNotFoundException(e.toString());
        } catch (IOException e) {
            throw new ClassNotFoundException(e.toString());
        } finally {
            if (iStream != null) {
                try {
                    iStream.close();
                } catch (Exception e) {
                    _logger.log(Level.SEVERE, "", e);
                }
            }
        }

    }

}

