/*
 * 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.jasper.compiler;

import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import jakarta.servlet.ServletContext;

import org.apache.jasper.Constants;
import org.apache.jasper.JasperException;
import org.apache.tomcat.Jar;
import org.apache.tomcat.util.descriptor.tld.TaglibXml;
import org.apache.tomcat.util.descriptor.tld.TldParser;
import org.apache.tomcat.util.descriptor.tld.TldResourcePath;
import org.xml.sax.SAXException;

/**
 * This class caches parsed instances of TLD files to remove the need for the
 * same TLD to be parsed for each JSP that references it. It does not protect
 * against multiple threads processing the same, new TLD but it does ensure that
 * each all threads will use the same TLD object after parsing.
 */
public class TldCache {

    public static final String SERVLET_CONTEXT_ATTRIBUTE_NAME =
            TldCache.class.getName();

    private final ServletContext servletContext;
    private final Map<String,TldResourcePath> uriTldResourcePathMap = new HashMap<>();
    private final Map<TldResourcePath,TaglibXmlCacheEntry> tldResourcePathTaglibXmlMap =
            new HashMap<>();
    private final TldParser tldParser;


    public static TldCache getInstance(ServletContext servletContext) {
        if (servletContext == null) {
            throw new IllegalArgumentException(Localizer.getMessage(
                    "org.apache.jasper.compiler.TldCache.servletContextNull"));
        }
        return (TldCache) servletContext.getAttribute(SERVLET_CONTEXT_ATTRIBUTE_NAME);
    }


    public TldCache(ServletContext servletContext,
            Map<String, TldResourcePath> uriTldResourcePathMap,
            Map<TldResourcePath, TaglibXml> tldResourcePathTaglibXmlMap) {
        this.servletContext = servletContext;
        this.uriTldResourcePathMap.putAll(uriTldResourcePathMap);
        for (Entry<TldResourcePath, TaglibXml> entry : tldResourcePathTaglibXmlMap.entrySet()) {
            TldResourcePath tldResourcePath = entry.getKey();
            long lastModified[] = getLastModified(tldResourcePath);
            TaglibXmlCacheEntry cacheEntry = new TaglibXmlCacheEntry(
                    entry.getValue(), lastModified[0], lastModified[1]);
            this.tldResourcePathTaglibXmlMap.put(tldResourcePath, cacheEntry);
        }
        boolean validate = Boolean.parseBoolean(
                servletContext.getInitParameter(Constants.XML_VALIDATION_TLD_INIT_PARAM));
        String blockExternalString = servletContext.getInitParameter(
                Constants.XML_BLOCK_EXTERNAL_INIT_PARAM);
        boolean blockExternal;
        if (blockExternalString == null) {
            blockExternal = true;
        } else {
            blockExternal = Boolean.parseBoolean(blockExternalString);
        }
        tldParser = new TldParser(true, validate, blockExternal);
    }


    public TldResourcePath getTldResourcePath(String uri) {
        return uriTldResourcePathMap.get(uri);
    }


    public TaglibXml getTaglibXml(TldResourcePath tldResourcePath) throws JasperException {
        TaglibXmlCacheEntry cacheEntry = tldResourcePathTaglibXmlMap.get(tldResourcePath);
        if (cacheEntry == null) {
            return null;
        }
        long lastModified[] = getLastModified(tldResourcePath);
        if (lastModified[0] != cacheEntry.getWebAppPathLastModified() ||
                lastModified[1] != cacheEntry.getEntryLastModified()) {
            synchronized (cacheEntry) {
                if (lastModified[0] != cacheEntry.getWebAppPathLastModified() ||
                        lastModified[1] != cacheEntry.getEntryLastModified()) {
                    // Re-parse TLD
                    TaglibXml updatedTaglibXml;
                    try {
                        updatedTaglibXml = tldParser.parse(tldResourcePath);
                    } catch (IOException | SAXException e) {
                        throw new JasperException(e);
                    }
                    cacheEntry.setTaglibXml(updatedTaglibXml);
                    cacheEntry.setWebAppPathLastModified(lastModified[0]);
                    cacheEntry.setEntryLastModified(lastModified[1]);
                }
            }
        }
        return cacheEntry.getTaglibXml();
    }


    private long[] getLastModified(TldResourcePath tldResourcePath) {
        long[] result = new long[2];
        result[0] = -1;
        result[1] = -1;
        try {
            String webappPath = tldResourcePath.getWebappPath();
            if (webappPath != null) {
                // webappPath will be null for JARs containing TLDs that are on
                // the class path but not part of the web application
                URL url = servletContext.getResource(tldResourcePath.getWebappPath());
                URLConnection conn = url.openConnection();
                result[0] = conn.getLastModified();
                if ("file".equals(url.getProtocol())) {
                    // Reading the last modified time opens an input stream so we
                    // need to make sure it is closed again otherwise the TLD file
                    // will be locked until GC runs.
                    conn.getInputStream().close();
                }
            }
            try (Jar jar = tldResourcePath.openJar()) {
                if (jar != null) {
                    result[1] = jar.getLastModified(tldResourcePath.getEntryName());
                }
            }
        } catch (IOException e) {
            // Ignore (shouldn't happen)
        }
        return result;
    }

    private static class TaglibXmlCacheEntry {
        private volatile TaglibXml taglibXml;
        private volatile long webAppPathLastModified;
        private volatile long entryLastModified;

        TaglibXmlCacheEntry(TaglibXml taglibXml, long webAppPathLastModified,
                long entryLastModified) {
            this.taglibXml = taglibXml;
            this.webAppPathLastModified = webAppPathLastModified;
            this.entryLastModified = entryLastModified;
        }

        public TaglibXml getTaglibXml() {
            return taglibXml;
        }

        public void setTaglibXml(TaglibXml taglibXml) {
            this.taglibXml = taglibXml;
        }

        public long getWebAppPathLastModified() {
            return webAppPathLastModified;
        }

        public void setWebAppPathLastModified(long webAppPathLastModified) {
            this.webAppPathLastModified = webAppPathLastModified;
        }

        public long getEntryLastModified() {
            return entryLastModified;
        }

        public void setEntryLastModified(long entryLastModified) {
            this.entryLastModified = entryLastModified;
        }
    }
}
