/*
 *  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.ivy.core.cache;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.ParseException;
import java.util.Map;
import java.util.Properties;

import org.apache.ivy.core.IvyPatternHelper;
import org.apache.ivy.core.RelativeUrlResolver;
import org.apache.ivy.core.module.descriptor.ExtendsDescriptor;
import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
import org.apache.ivy.core.module.id.ModuleId;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.core.module.status.StatusManager;
import org.apache.ivy.core.settings.IvySettings;
import org.apache.ivy.plugins.IvySettingsAware;
import org.apache.ivy.plugins.conflict.ConflictManager;
import org.apache.ivy.plugins.matcher.PatternMatcher;
import org.apache.ivy.plugins.namespace.Namespace;
import org.apache.ivy.plugins.parser.ModuleDescriptorParser;
import org.apache.ivy.plugins.parser.ModuleDescriptorParserRegistry;
import org.apache.ivy.plugins.parser.ParserSettings;
import org.apache.ivy.plugins.repository.url.URLResource;
import org.apache.ivy.plugins.resolver.DependencyResolver;
import org.apache.ivy.util.FileUtil;

public class EasyantResolutionCacheManager implements ResolutionCacheManager, IvySettingsAware {

    private static final String DEFAULT_CACHE_RESOLVED_IVY_PATTERN = "resolved-[organisation]-[module]-[revision].xml";

    private static final String DEFAULT_CACHE_RESOLVED_IVY_PROPERTIES_PATTERN = "resolved-[organisation]-[module]-[revision].properties";

    private String resolvedIvyPattern = DEFAULT_CACHE_RESOLVED_IVY_PATTERN;

    private String resolvedIvyPropertiesPattern = DEFAULT_CACHE_RESOLVED_IVY_PROPERTIES_PATTERN;

    private File basedir;

    private String name = "resolution-cache";

    private IvySettings settings;

    public EasyantResolutionCacheManager() {
    }

    public EasyantResolutionCacheManager(File basedir) {
        setBasedir(basedir);
    }

    public void setSettings(IvySettings settings) {
        this.settings = settings;
    }

    public File getResolutionCacheRoot() {
        return basedir;
    }

    public File getBasedir() {
        return basedir;
    }

    public void setBasedir(File basedir) {
        this.basedir = basedir;
    }

    public String getResolvedIvyPattern() {
        return resolvedIvyPattern;
    }

    public void setResolvedIvyPattern(String cacheResolvedIvyPattern) {
        this.resolvedIvyPattern = cacheResolvedIvyPattern;
    }

    public String getResolvedIvyPropertiesPattern() {
        return resolvedIvyPropertiesPattern;
    }

    public void setResolvedIvyPropertiesPattern(String cacheResolvedIvyPropertiesPattern) {
        this.resolvedIvyPropertiesPattern = cacheResolvedIvyPropertiesPattern;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public File getResolvedIvyFileInCache(ModuleRevisionId mrid) {
        String file = IvyPatternHelper.substitute(getResolvedIvyPattern(), mrid.getOrganisation(), mrid.getName(),
                mrid.getRevision(), "ivy", "ivy", "xml");
        return new File(getResolutionCacheRoot(), file);
    }

    public File getResolvedIvyPropertiesInCache(ModuleRevisionId mrid) {
        String file = IvyPatternHelper.substitute(getResolvedIvyPropertiesPattern(), mrid.getOrganisation(),
                mrid.getName(), mrid.getRevision(), "ivy", "ivy", "xml");
        return new File(getResolutionCacheRoot(), file);
    }

    public File getConfigurationResolveReportInCache(String resolveId, String conf) {
        return new File(getResolutionCacheRoot(), resolveId + "-" + conf + ".xml");
    }

    public File[] getConfigurationResolveReportsInCache(final String resolveId) {
        final String prefix = resolveId + "-";
        final String suffix = ".xml";
        return getResolutionCacheRoot().listFiles(new FilenameFilter() {
            public boolean accept(File dir, String name) {
                return (name.startsWith(prefix) && name.endsWith(suffix));
            }
        });
    }

    public ModuleDescriptor getResolvedModuleDescriptor(ModuleRevisionId mrid) throws ParseException, IOException {
        File ivyFile = getResolvedIvyFileInCache(mrid);
        if (!ivyFile.exists()) {
            throw new IllegalStateException("Ivy file not found in cache for " + mrid + "!");
        }

        Properties paths = new Properties();

        File parentsFile = getResolvedIvyPropertiesInCache(ModuleRevisionId.newInstance(mrid, mrid.getRevision()
                + "-parents"));
        if (parentsFile.exists()) {
            FileInputStream in = null;
            try {
                in = new FileInputStream(parentsFile);
                paths.load(in);

            } finally {
                if (in != null) {
                    in.close();
                }
            }
        }

        ParserSettings pSettings = new CacheParserSettings(settings, paths);

        URL ivyFileURL = ivyFile.toURI().toURL();
        ModuleDescriptorParser parser = ModuleDescriptorParserRegistry.getInstance().getParser(
                new URLResource(ivyFileURL));
        return parser.parseDescriptor(pSettings, ivyFileURL, false);
    }

    public void saveResolvedModuleDescriptor(ModuleDescriptor md) throws ParseException, IOException {
        ModuleRevisionId mrevId = md.getResolvedModuleRevisionId();
        File ivyFileInCache = getResolvedIvyFileInCache(mrevId);
        md.toIvyFile(ivyFileInCache);

        Properties paths = new Properties();
        saveLocalParents(mrevId, md, ivyFileInCache, paths);

        if (!paths.isEmpty()) {
            File parentsFile = getResolvedIvyPropertiesInCache(ModuleRevisionId.newInstance(mrevId,
                    mrevId.getRevision() + "-parents"));
            FileOutputStream out = null;
            try {
                out = new FileOutputStream(parentsFile);
                paths.store(out, null);
            } finally {
                if (out != null) {
                    out.close();
                }
            }
        }
    }

    private void saveLocalParents(ModuleRevisionId baseMrevId, ModuleDescriptor md, File mdFile, Properties paths)
            throws ParseException, IOException {
        ExtendsDescriptor[] parents = md.getInheritedDescriptors();
        for (ExtendsDescriptor parent1 : parents) {
            if (!parent1.isLocal()) {
                // we store only local parents in the cache!
                continue;
            }

            ModuleDescriptor parent = parent1.getParentMd();
            ModuleRevisionId pRevId = ModuleRevisionId.newInstance(baseMrevId, baseMrevId.getRevision() + "-parent."
                    + paths.size());
            File parentFile = getResolvedIvyFileInCache(pRevId);
            parent.toIvyFile(parentFile);

            paths.setProperty(mdFile.getName() + "|" + parent1.getLocation(), parentFile.getAbsolutePath());
            saveLocalParents(baseMrevId, parent, parentFile, paths);
        }
    }

    public String toString() {
        return name;
    }

    public void clean() {
        FileUtil.forceDelete(getBasedir());
    }

    private static class CacheParserSettings implements ParserSettings {

        private ParserSettings delegate;
        private Map parentPaths;

        public CacheParserSettings(ParserSettings delegate, Map parentPaths) {
            this.delegate = delegate;
            this.parentPaths = parentPaths;
        }

        public String substitute(String value) {
            return delegate.substitute(value);
        }

        public Map substitute(Map strings) {
            return delegate.substitute(strings);
        }

        public ResolutionCacheManager getResolutionCacheManager() {
            return delegate.getResolutionCacheManager();
        }

        public ConflictManager getConflictManager(String name) {
            return delegate.getConflictManager(name);
        }

        public PatternMatcher getMatcher(String matcherName) {
            return delegate.getMatcher(matcherName);
        }

        public Namespace getNamespace(String namespace) {
            return delegate.getNamespace(namespace);
        }

        public StatusManager getStatusManager() {
            return delegate.getStatusManager();
        }

        public RelativeUrlResolver getRelativeUrlResolver() {
            return new MapURLResolver(parentPaths, delegate.getRelativeUrlResolver());
        }

        public DependencyResolver getResolver(ModuleRevisionId mRevId) {
            return delegate.getResolver(mRevId);
        }

        public File resolveFile(String filename) {
            return delegate.resolveFile(filename);
        }

        public String getDefaultBranch(ModuleId moduleId) {
            return delegate.getDefaultBranch(moduleId);
        }

        public Namespace getContextNamespace() {
            return delegate.getContextNamespace();
        }
    }

    private static class MapURLResolver extends RelativeUrlResolver {

        private Map paths;
        private RelativeUrlResolver delegate;

        private MapURLResolver(Map paths, RelativeUrlResolver delegate) {
            this.paths = paths;
            this.delegate = delegate;
        }

        public URL getURL(URL context, String url) throws MalformedURLException {
            String path = context.getPath();
            if (path.indexOf('/') >= 0) {
                String file = path.substring(path.lastIndexOf('/') + 1);

                if (paths.containsKey(file + "|" + url)) {
                    File result = new File(paths.get(file + "|" + url).toString());
                    return result.toURI().toURL();
                }
            }

            return delegate.getURL(context, url);
        }
    }
}
