/*
 * 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.uima.fit.factory;

import static org.apache.uima.UIMAFramework.getXMLParser;
import static org.apache.uima.fit.internal.MetaDataUtil.scanDescriptors;
import static org.apache.uima.util.CasCreationUtils.mergeTypeSystems;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.WeakHashMap;

import org.apache.commons.logging.LogFactory;
import org.apache.uima.fit.internal.ClassLoaderUtils;
import org.apache.uima.fit.internal.MetaDataType;
import org.apache.uima.fit.internal.ResourceManagerFactory;
import org.apache.uima.resource.ResourceInitializationException;
import org.apache.uima.resource.ResourceManager;
import org.apache.uima.resource.metadata.Import;
import org.apache.uima.resource.metadata.TypeSystemDescription;
import org.apache.uima.resource.metadata.impl.Import_impl;
import org.apache.uima.resource.metadata.impl.TypeSystemDescription_impl;
import org.apache.uima.util.InvalidXMLException;
import org.apache.uima.util.XMLInputSource;

public final class TypeSystemDescriptionFactory {
  private static final Object SCAN_LOCK = new Object();

  private static final Object CREATE_LOCK = new Object();

  private static WeakHashMap<ClassLoader, String[]> typeDescriptorLocationsByClassloader;

  private static WeakHashMap<ClassLoader, TypeSystemDescription> typeDescriptorByClassloader;

  static {
    typeDescriptorLocationsByClassloader = new WeakHashMap<>();
    typeDescriptorByClassloader = new WeakHashMap<>();
  }

  private TypeSystemDescriptionFactory() {
    // This class is not meant to be instantiated
  }

  /**
   * Creates a TypeSystemDescription from descriptor names.
   *
   * @param descriptorNames
   *          The fully qualified, Java-style, dotted descriptor names.
   * @return A TypeSystemDescription that includes the types from all of the specified files.
   */
  public static TypeSystemDescription createTypeSystemDescription(String... descriptorNames) {
    TypeSystemDescription typeSystem = new TypeSystemDescription_impl();
    List<Import> imports = new ArrayList<>();
    for (String descriptorName : descriptorNames) {
      Import imp = new Import_impl();
      imp.setName(descriptorName);
      imports.add(imp);
    }
    Import[] importArray = new Import[imports.size()];
    typeSystem.setImports(imports.toArray(importArray));
    return typeSystem;
  }

  /**
   * Creates a {@link TypeSystemDescription} from a descriptor file
   *
   * @param descriptorURIs
   *          The descriptor file paths.
   * @return A TypeSystemDescription that includes the types from all of the specified files.
   */
  public static TypeSystemDescription createTypeSystemDescriptionFromPath(
          String... descriptorURIs) {
    TypeSystemDescription typeSystem = new TypeSystemDescription_impl();
    List<Import> imports = new ArrayList<>();
    for (String descriptorURI : descriptorURIs) {
      Import imp = new Import_impl();
      imp.setLocation(descriptorURI);
      imports.add(imp);
    }
    Import[] importArray = new Import[imports.size()];
    typeSystem.setImports(imports.toArray(importArray));
    return typeSystem;
  }

  /**
   * Creates a {@link TypeSystemDescription} from all type descriptions that can be found via the
   * default import pattern or via the {@code META-INF/org.apache.uima.fit/types.txt} files in the
   * classpath.
   *
   * @return the auto-scanned type system.
   * @throws ResourceInitializationException
   *           if the collected type system descriptions cannot be merged.
   */
  public static TypeSystemDescription createTypeSystemDescription()
          throws ResourceInitializationException {
    ClassLoader cl = ClassLoaderUtils.findClassloader();
    TypeSystemDescription tsd = typeDescriptorByClassloader.get(cl);
    if (tsd == null) {
      synchronized (CREATE_LOCK) {
        List<TypeSystemDescription> tsdList = new ArrayList<>();
        for (String location : scanTypeDescriptors()) {
          try {
            XMLInputSource xmlInputType1 = new XMLInputSource(location);
            tsdList.add(getXMLParser().parseTypeSystemDescription(xmlInputType1));
            LogFactory.getLog(TypeSystemDescription.class)
            .debug("Detected type system at [" + location + "]");
          } catch (IOException e) {
            throw new ResourceInitializationException(e);
          } catch (InvalidXMLException e) {
            LogFactory.getLog(TypeSystemDescription.class)
            .warn("[" + location + "] is not a type file. Ignoring.", e);
          }
        }

        ResourceManager resMgr = ResourceManagerFactory.newResourceManager();
        tsd = mergeTypeSystems(tsdList, resMgr);
        typeDescriptorByClassloader.put(cl, tsd);
      }
    }
    return (TypeSystemDescription) tsd.clone();
  }

  /**
   * Get all currently accessible type system descriptor locations. A scan is actually only
   * performed on the first call and the locations are cached. To force a re-scan use
   * {@link #forceTypeDescriptorsScan()}.
   *
   * @return an array of locations.
   * @throws ResourceInitializationException
   *           if the locations could not be resolved.
   */
  public static String[] scanTypeDescriptors() throws ResourceInitializationException {
    synchronized (SCAN_LOCK) {
      ClassLoader cl = ClassLoaderUtils.findClassloader();
      String[] typeDescriptorLocations = typeDescriptorLocationsByClassloader.get(cl);
      if (typeDescriptorLocations == null) {
        typeDescriptorLocations = scanDescriptors(MetaDataType.TYPE_SYSTEM);
        typeDescriptorLocationsByClassloader.put(cl, typeDescriptorLocations);
      }
      return typeDescriptorLocations;
    }
  }

  /**
   * Force rescan of type descriptors. The next call to {@link #scanTypeDescriptors()} will rescan
   * all auto-import locations.
   */
  public static void forceTypeDescriptorsScan() {
    synchronized (SCAN_LOCK) {
      typeDescriptorLocationsByClassloader.clear();
      typeDescriptorByClassloader.clear();
    }
  }
}
