/*
 * Copyright 2006-2012 The Apache Software Foundation.
 *
 * Licensed 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
 *
 *      https://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.jdo.exectck;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;

/** Helper class that sets properties required for running the JDO TCK. */
public class PropertyUtils {

  /**
   * Separates white space separated items from a String into Collection entries Used to collect
   * command line argument lists into a Collection
   *
   * @param names String of white space separated items
   * @param list HashSet to contain String items
   */
  public static void string2Set(String names, Collection<String> list) {
    String[] items = names.split("[ \t\n]");
    for (String s : items) {
      list.add(s);
    }
  }

  /**
   * Separates white space separated items from a String into HashSet entries Used to collect
   * command line argument lists into a Collection
   *
   * @param names String of white space separated items
   * @param list HashSet to contain String items
   */
  public static void string2List(String names, List<String> list) {
    //        System.out.println("names are " + names);
    String[] items = names.split("[ \t\n]");
    for (String s : items) {
      list.add(s);
    }
    //        System.out.println("List names are " + list.toString());
  }

  /**
   * Parses a set of config files for the mapping entry and provides the mapping values in a
   * Collection.
   *
   * @param cfglist config file names
   * @param confDir directory where config files are found
   * @param mappings object to containg mapping values
   */
  public static void mappingsSet(
      Collection<String> cfglist, String confDir, Collection<String> mappings) {

    for (String cfg : cfglist) {
      String mapping = "";
      String confName = confDir + File.separator + cfg;

      Properties props = new Properties();
      FileInputStream fis = null;
      //            System.out.println("confName is " + confName);
      try {
        fis = new FileInputStream(confName);
        props.load(fis);
        mapping = props.getProperty("jdo.tck.mapping");
        //                System.out.println("Next mapping is " + mapping);
      } catch (IOException e) {
        e.printStackTrace();
        try {
          if (fis != null) {
            fis.close();
          }
        } catch (IOException ex) {
          Logger.getLogger(PropertyUtils.class.getName()).log(Level.SEVERE, null, ex);
        }
        return;
      }

      mappings.add(mapping);
    }
  }

  /*
   * Open a properties file and return a Properties object
   */
  public static Properties getProperties(String fname) {
    Properties props = new Properties();
    FileInputStream fis = null;
    try {
      fis = new FileInputStream(new File(fname));
      props.load(fis);
    } catch (IOException e) {
      e.printStackTrace();
      try {
        if (fis != null) {
          fis.close();
        }
      } catch (IOException ex) {
        Logger.getLogger(PropertyUtils.class.getName()).log(Level.SEVERE, null, ex);
      }
    }
    return props;
  }

  /*
   * Set the value of key if found in properties.
   */
  public static void setSysProperty(Properties properties, String key, String newkey) {
    String value = properties.getProperty("key");
    if (value != null) {
      System.setProperty(newkey, value);
    }
  }

  public static void setSysProperty(Properties properties, String key) {
    setSysProperty(properties, key, key);
  }
}
