/*
 * 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.fit.util.CasUtil.UIMA_BUILTIN_JCAS_PREFIX;

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

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.jcas.cas.TOP;
import org.apache.uima.resource.ResourceInitializationException;
import org.apache.uima.resource.ResourceManager;
import org.apache.uima.resource.metadata.TypePriorities;
import org.apache.uima.resource.metadata.TypePriorityList;
import org.apache.uima.resource.metadata.impl.TypePriorities_impl;
import org.apache.uima.util.CasCreationUtils;
import org.apache.uima.util.InvalidXMLException;
import org.apache.uima.util.XMLInputSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public final class TypePrioritiesFactory {
  private static final Logger LOG = LoggerFactory.getLogger(TypePrioritiesFactory.class);

  private static final Object SCAN_LOCK = new Object();

  private static final Object CREATE_LOCK = new Object();

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

  private static WeakHashMap<ClassLoader, TypePriorities> typePrioritiesByClassloader;

  static {
    typePrioritesLocationsByClassloader = new WeakHashMap<>();
    typePrioritiesByClassloader = new WeakHashMap<>();
  }

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

  /**
   * Create a TypePriorities given a sequence of ordered type classes
   *
   * @param prioritizedTypes
   *          a sequence of ordered type classes
   * @return type priorities created from the ordered JCas classes
   */
  @SafeVarargs
  public static TypePriorities createTypePriorities(Class<? extends TOP>... prioritizedTypes) {
    String[] typeNames = new String[prioritizedTypes.length];
    for (int i = 0; i < prioritizedTypes.length; i++) {
      if (!TOP.class.isAssignableFrom(prioritizedTypes[i])) {
        throw new IllegalArgumentException("[" + prioritizedTypes[i] + "] is not a JCas type");
      }

      String typeName = prioritizedTypes[i].getName();
      if (typeName.startsWith(UIMA_BUILTIN_JCAS_PREFIX)) {
        typeName = "uima." + typeName.substring(UIMA_BUILTIN_JCAS_PREFIX.length());
      }

      typeNames[i] = typeName;
    }
    return createTypePriorities(typeNames);
  }

  /**
   * Create a {@link TypePriorities} given a sequence of ordered type names
   *
   * @param prioritizedTypeNames
   *          a sequence of ordered type names
   * @return type priorities created from the ordered type names
   */
  public static TypePriorities createTypePriorities(String... prioritizedTypeNames) {
    TypePriorities typePriorities = new TypePriorities_impl();
    TypePriorityList typePriorityList = typePriorities.addPriorityList();
    for (String typeName : prioritizedTypeNames) {
      typePriorityList.addType(typeName);
    }
    return typePriorities;
  }

  /**
   * Creates a {@link TypePriorities} from all type priorities descriptions that can be found via
   * the pattern specified in the system property
   * {@code org.apache.uima.fit.typepriorities.import_pattern} or via the
   * {@code META-INF/org.apache.uima.fit/typepriorities.txt} files in the classpath.
   *
   * @return the auto-scanned type priorities.
   * @throws ResourceInitializationException
   *           if the collected type priorities cannot be merged.
   */
  public static TypePriorities createTypePriorities() throws ResourceInitializationException {
    ClassLoader cl = ClassLoaderUtils.findClassloader();
    TypePriorities aggTypePriorities = typePrioritiesByClassloader.get(cl);
    if (aggTypePriorities == null) {
      synchronized (CREATE_LOCK) {
        List<TypePriorities> typePrioritiesList = new ArrayList<>();
        for (String location : scanTypePrioritiesDescriptors()) {
          try {
            XMLInputSource xmlInput = new XMLInputSource(location);
            TypePriorities typePriorities = getXMLParser().parseTypePriorities(xmlInput);
            typePriorities.resolveImports();
            typePrioritiesList.add(typePriorities);
            LOG.debug("Detected type priorities at [{}]", location);
          } catch (IOException e) {
            throw new ResourceInitializationException(e);
          } catch (InvalidXMLException e) {
            LOG.warn("[{}] is not a type priorities descriptor file. Ignoring.", location, e);
          }
        }

        ResourceManager resMgr = ResourceManagerFactory.newResourceManager();
        aggTypePriorities = CasCreationUtils.mergeTypePriorities(typePrioritiesList, resMgr);
        typePrioritiesByClassloader.put(cl, aggTypePriorities);
      }
    }

    return (TypePriorities) aggTypePriorities.clone();
  }

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

  /**
   * Force rescan of type priorities descriptors. The next call to
   * {@link #scanTypePrioritiesDescriptors()} will rescan all auto-import locations.
   */
  public static void forceTypePrioritiesDescriptorsScan() {
    synchronized (SCAN_LOCK) {
      typePrioritesLocationsByClassloader.clear();
      typePrioritiesByClassloader.clear();
    }
  }
}
