/*
 * 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 rewrite.org.apache.myfaces.extensions.scripting.core.engine;

import org.apache.commons.io.FilenameUtils;
import org.apache.myfaces.extensions.scripting.core.util.FileUtils;
import org.apache.myfaces.extensions.scripting.monitor.WatchedResource;
import rewrite.org.apache.myfaces.extensions.scripting.core.common.util.ClassUtils;
import rewrite.org.apache.myfaces.extensions.scripting.core.engine.dependencyScan.api.DependencyRegistry;
import rewrite.org.apache.myfaces.extensions.scripting.core.engine.dependencyScan.core.ClassDependencies;
import rewrite.org.apache.myfaces.extensions.scripting.core.engine.dependencyScan.registry.DependencyRegistryImpl;
import rewrite.org.apache.myfaces.extensions.scripting.core.engine.dependencyScan.registry.DependencyRegistryImpl;
import rewrite.org.apache.myfaces.extensions.scripting.core.monitor.ClassResource;

import javax.servlet.ServletContext;
import java.io.File;
import java.net.URL;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Logger;

import static rewrite.org.apache.myfaces.extensions.scripting.core.common.ScriptingConst.JAVA_SOURCE_ROOT;

/**
 * @author Werner Punz (latest modification by $Author$)
 * @version $Revision$ $Date$
 */

public abstract class BaseEngine
{
    CopyOnWriteArrayList<String> _sourcePaths = new CopyOnWriteArrayList<String>();
    Map<String, ClassResource> _watchedResources = new ConcurrentHashMap<String, ClassResource>();
    //both belong together but the dependencyregistry is just
    //a wrapper for the dep map with additional functionality
    ClassDependencies _dependencyMap = new ClassDependencies();
    DependencyRegistry _dependencyRegistry = new DependencyRegistryImpl(getEngineType(), _dependencyMap);

    Logger log = Logger.getLogger(this.getClass().getName());
    
    public Map<String, ClassResource> getWatchedResources()
    {
        return _watchedResources;
    }

    public List<String> getSourcePaths()
    {
        return _sourcePaths;
    }

    public abstract String getFileEnding();

    public abstract int getEngineType();

    /**
     * @return a collection of possible dynamic classes
     */
    public Collection<String> getPossibleDynamicClasses() {
        return _watchedResources.keySet();
    }

    /**
     * runs a full scan of files to get a list of files which need to be processed
     * for the future
     */
    public void scanForAddedDeleted() {
        Set<String> processedClasses = new HashSet<String>();
        processedClasses.addAll(_watchedResources.keySet());
        
        for(String sourcePath: getSourcePaths()) {
           Collection<File> sourceFiles = FileUtils.fetchSourceFiles(new File(sourcePath), "*."+ getFileEnding());
           
            for(File sourceFile: sourceFiles) {
               ClassResource classToProcess = new ClassResource();
                classToProcess.setFile(sourceFile);
                classToProcess.setLastLoaded(-1);
                classToProcess.setScriptingEngine(getEngineType());
                if(!_watchedResources.containsKey(classToProcess.getIdentifier())) {
                    _watchedResources.put(classToProcess.getIdentifier(), classToProcess);
               } else {
                   processedClasses.remove(classToProcess.getIdentifier());
                   
                   classToProcess = _watchedResources.get(classToProcess.getIdentifier());
               }
               if(classToProcess.needsRecompile()) {
                   //TODO add entry for logging component here
                   log.info("[EXT-SCRIPTING] tainting "+classToProcess.getIdentifier());
                   classToProcess.setTainted(true);
                   classToProcess.setChangedForCompile(true);
               }
           }
        }
        for(String deleted:processedClasses) {
            _watchedResources.remove(deleted);
        }


    }

    /**
     * checks whether we have resources which are in need of a recompile
     * @return
     */
    public boolean needsRecompile() {
        //TODO buffer this from scan
        for(Map.Entry<String, ClassResource> resource: _watchedResources.entrySet()) {
            if(resource.getValue().needsRecompile()) return true;
        }
        return false;
    }

    /**
     * checks whether we have resources which are tainted
     * @return
     */
    public boolean isTainted() {
        //TODO buffer this from scan
        for(Map.Entry<String, ClassResource> resource: _watchedResources.entrySet()) {
            if(resource.getValue().isTainted()) return true;
        }
        return false;
    }

    protected void initPaths(ServletContext context, String initParam, String defaultValue)
    {
        String pathSeparatedList = context.getInitParameter(initParam);
        pathSeparatedList = (pathSeparatedList != null) ? pathSeparatedList : defaultValue;
        if (pathSeparatedList.equals(JAVA_SOURCE_ROOT))
        {
            URL resource = ClassUtils.getContextClassLoader().getResource("./");
            pathSeparatedList = FilenameUtils.normalize(resource.getPath() + "../.." + defaultValue);
        }
        String[] paths = pathSeparatedList.split(",");
        for (String path : paths)
        {
            getSourcePaths().add(path);
        }
    }

    public DependencyRegistry getDependencyRegistry()
    {
        return _dependencyRegistry;
    }

    public void setDependencyRegistry(DependencyRegistry dependencyRegistry)
    {
        _dependencyRegistry = dependencyRegistry;
    }

    public ClassDependencies getDependencyMap()
    {
        return _dependencyMap;
    }

    public void setDependencyMap(ClassDependencies dependencyMap)
    {
        _dependencyMap = dependencyMap;
    }


    
    /**
     * marks all the dependencies of the tainted objects
     * also as tainted to allow proper refreshing.
     */
    public void markTaintedDependencies()
    {
        //basic tainted set by the full scall
        Set<String> _processedClasses = new HashSet<String>();
        for (Map.Entry<String, ClassResource> entry : _watchedResources.entrySet())
        {
            //TODO add entry for logging component here
            ClassResource resource = entry.getValue();
            if (!resource.isChangedForCompile()) continue;
            resource.setChangedForCompile(false);
            log.info("[EXT-SCRIPTING] tainting dependency "+resource.getIdentifier());
            resource.setTainted(true);
            //classname
            String identifier = resource.getIdentifier();
            if (_processedClasses.contains(identifier)) continue;
            markDependencies(_processedClasses, identifier);

        }

    }

    /*marks all backward dependencies of the existing class*/
    private void markDependencies(Set<String> _processedClasses, String identifier)
    {
        Set<String> referringClasses = _dependencyMap.getReferringClasses(identifier);
        if(referringClasses == null) return;
        for (String referringClass : referringClasses)
        {
            if (_processedClasses.contains(referringClass)) continue;
            ClassResource toTaint = _watchedResources.get(referringClass);
            if(toTaint == null) continue;
            //TODO add entry for logging component here
            if(toTaint.isTainted()) {
                log.info("[EXT-SCRIPTING] dependency already tainted:"+toTaint.getIdentifier());
                _processedClasses.add(toTaint.getIdentifier());
                continue;
            }
            toTaint.setTainted(true);
            toTaint.setChangedForCompile(false);
            log.info("[EXT-SCRIPTING] tainting dependency "+toTaint.getIdentifier());
            _processedClasses.add(toTaint.getIdentifier());
            markDependencies(_processedClasses, toTaint.getIdentifier());
        }

    }
}
