/* Copyright (c) 2008 Charles Rich and Worcester Polytechnic Institute.
 * All Rights Reserved.  Use is subject to license terms.  See the file
 * "license.terms" for information on usage and redistribution of this
 * file and for a DISCLAIMER OF ALL WARRANTIES.
 */
package edu.wpi.cetask;

import com.thaiopensource.datatype.xsd.DatatypeLibraryFactoryImpl;
import com.thaiopensource.util.PropertyMapBuilder;
import com.thaiopensource.validate.ValidationDriver;
import com.thaiopensource.validate.rng.*;

import org.xml.sax.InputSource;

import java.io.*;
import java.net.*;

public abstract class Utils {

   private Utils () {}  // non-instantiatable class for static methods only

   /**
    * Validate given task model description against CEA-2018 RelaxNG schema
    * (http://ce.org/cea-2018/rnc). Validation can also be run stand-alone at command
    * line as in:<br>
    * <br>
    * <tt>java -jar lib/jing.jar -c java/edu/wpi/cetask/CEA-2018.rnc MyModel.xml</tt>
    * 
    * @param uri of xml file to validate
    * @return true iff file is valid
    */
   public static boolean validate (String uri) {
      // explicit datatype factory is workaround for Jing bug wrt to OS X
      PropertyMapBuilder properties = new PropertyMapBuilder();
      RngProperty.DATATYPE_LIBRARY_FACTORY.put(properties,
            new DatatypeLibraryFactoryImpl());
      ValidationDriver driver = 
         new ValidationDriver(properties.toPropertyMap(),
               CompactSchemaReader.getInstance());
      try {
         driver.loadSchema(
               new InputSource(Utils.class.getResourceAsStream("cea-2018.rnc")));
         return driver.validate(new InputSource(ClassLoader.getSystemResourceAsStream(uri)));
      } catch (Exception e) { 
         System.out.println(e);
         return false;
      }
   }
   
   // three-valued logic (null represents unknown)
   
   public static boolean isTrue (Boolean b) {
      return b != null && b;
   }
   
   public static boolean isFalse (Boolean b) {
      return b != null && !b;
   }

   /**
    * Test whether given objects are either both null or
    * {@link java.lang#equal(Object,Object)}. 
    */
   public static boolean equals (Object object1, Object object2) {
      return object1 == null ? object2 == null : object1.equals(object2);
   }
   
   /**
    * Return null if given string is empty, otherwise string.  
    */
   public static String emptyNull (String string) {
      return string.length() == 0 ? null : string;
   }
   
   /**
    * Convert the given source string to a URL.  If given string is not a well-formed
    * URL, then see if it names a system resource; otherwise treat it as a filename.
    */
   public static URL toURL (String source) throws MalformedURLException {
      try { return new URL(source); }
      catch (MalformedURLException e) {
         URL url = ClassLoader.getSystemResource(source);
         return url == null ? new File(source).toURI().toURL() : url;
      }
   }
   
   /**
    * If given string ends with 'from' string, replace ending with 'to' string;
    * otherwise just append 'to' string.
    */
   public static String replaceEndsWith (String string, String from, String to) {
      return ( string.endsWith(from) ?
         string.substring(0, string.length()-from.length()) : string) 
         + to;
   }
   
   /**
    * Return (possibly copy of) given string with first character lower case.
    */
   public static String decapitalize (String string) {
      if ( Character.isLowerCase(string.charAt(0)) ) return string;
      char chars[] = string.toCharArray();
      chars[0] = Character.toLowerCase(chars[0]);
      return new String(chars);
   }
}
