package org.apache.solr.util;

/*
 * 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.
 */

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.lucene.analysis.util.ResourceLoader;

import org.xml.sax.InputSource;
import org.xml.sax.EntityResolver;
import org.xml.sax.ext.EntityResolver2;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver;
import javax.xml.transform.sax.SAXSource;
import javax.xml.stream.XMLResolver;
import javax.xml.stream.XMLStreamException;

/**
 * This is a helper class to support resolving of XIncludes or other hrefs
 * inside XML files on top of a {@link ResourceLoader}. Just plug this class
 * on top of a {@link ResourceLoader} and pass it as {@link EntityResolver} to SAX parsers
 * or via wrapper methods as {@link URIResolver} to XSL transformers or {@link XMLResolver} to STAX parsers.
 * The resolver handles special SystemIds with an URI scheme of {@code solrres:} that point
 * to resources. To produce such systemIds when you initially call the parser, use
 * {@link #createSystemIdFromResourceName} which produces a SystemId that can
 * be included along the InputStream coming from {@link ResourceLoader#openResource}.
 * <p>In general create the {@link InputSource} to be passed to the parser like:</p>
 * <pre class="prettyprint">
 *  InputSource is = new InputSource(loader.openSchema(name));
 *  is.setSystemId(SystemIdResolver.createSystemIdFromResourceName(name));
 *  final DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
 *  db.setEntityResolver(new SystemIdResolver(loader));
 *  Document doc = db.parse(is);
 * </pre>
 */
public final class SystemIdResolver implements EntityResolver, EntityResolver2 {
  private static final Logger log = LoggerFactory.getLogger(SystemIdResolver.class);

  public static final String RESOURCE_LOADER_URI_SCHEME = "solrres";
  public static final String RESOURCE_LOADER_AUTHORITY_ABSOLUTE = "@";

  private final ResourceLoader loader;

  public SystemIdResolver(ResourceLoader loader) {
    this.loader = loader;
  }
  
  public EntityResolver asEntityResolver() {
    return this;
  }
  
  public URIResolver asURIResolver() {
    return new URIResolver() {
      @Override
      public Source resolve(String href, String base) throws TransformerException {
        try {
          final InputSource src = SystemIdResolver.this.resolveEntity(null, null, base, href);
          return (src == null) ? null : new SAXSource(src);
        } catch (IOException ioe) {
          throw new TransformerException("Cannot resolve entity", ioe);
        }
      }
    };
  }
  
  public XMLResolver asXMLResolver() {
    return new XMLResolver() {
      @Override
      public Object resolveEntity(String publicId, String systemId, String baseURI, String namespace) throws XMLStreamException {
        try {
          final InputSource src = SystemIdResolver.this.resolveEntity(null, publicId, baseURI, systemId);
          return (src == null) ? null : src.getByteStream();
        } catch (IOException ioe) {
          throw new XMLStreamException("Cannot resolve entity", ioe);
        }
      }
    };
  }
  
  URI resolveRelativeURI(String baseURI, String systemId) throws URISyntaxException {
    URI uri;
    
    // special case for backwards compatibility: if relative systemId starts with "/" (we convert that to an absolute solrres:-URI)
    if (systemId.startsWith("/")) {
      uri = new URI(RESOURCE_LOADER_URI_SCHEME, RESOURCE_LOADER_AUTHORITY_ABSOLUTE, "/", null, null).resolve(systemId);
    } else {
      // simply parse as URI
      uri = new URI(systemId);
    }
    
    // do relative resolving
    if (baseURI != null ) {
      uri = new URI(baseURI).resolve(uri);
    }
    
    return uri;
  }
  
  // *** EntityResolver(2) methods:
  
  @Override
  public InputSource getExternalSubset(String name, String baseURI) {
    return null;
  }
  
  @Override
  public InputSource resolveEntity(String name, String publicId, String baseURI, String systemId) throws IOException {
    if (systemId == null)
      return null;
    try {
      final URI uri = resolveRelativeURI(baseURI, systemId);
      
      // check schema and resolve with ResourceLoader
      if (RESOURCE_LOADER_URI_SCHEME.equals(uri.getScheme())) {
        String path = uri.getPath(), authority = uri.getAuthority();
        if (!RESOURCE_LOADER_AUTHORITY_ABSOLUTE.equals(authority)) {
          path = path.substring(1);
        }
        try {
          final InputSource is = new InputSource(loader.openResource(path));
          is.setSystemId(uri.toASCIIString());
          is.setPublicId(publicId);
          return is;
        } catch (RuntimeException re) {
          // unfortunately XInclude fallback only works with IOException, but openResource() never throws that one
          throw (IOException) (new IOException(re.getMessage()).initCause(re));
        }
      } else {
        // resolve all other URIs using the standard resolver
        return null;
      }
    } catch (URISyntaxException use) {
      log.warn("An URI systax problem occurred during resolving SystemId, falling back to default resolver", use);
      return null;
    }
  }

  @Override
  public InputSource resolveEntity(String publicId, String systemId) throws IOException {
    return resolveEntity(null, publicId, null, systemId);
  }
  
  public static String createSystemIdFromResourceName(String name) {
    name = name.replace(File.separatorChar, '/');
    final String authority;
    if (name.startsWith("/")) {
      // a hack to preserve absolute filenames and keep them absolute after resolving, we set the URI's authority to "@" on absolute filenames:
      authority = RESOURCE_LOADER_AUTHORITY_ABSOLUTE;
    } else {
      authority = null;
      name = "/" + name;
    }
    try {
      return new URI(RESOURCE_LOADER_URI_SCHEME, authority, name, null, null).toASCIIString();
    } catch (URISyntaxException use) {
      throw new IllegalArgumentException("Invalid syntax of Solr Resource URI", use);
    }
  }

}
