/*
 * 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
<<<<<<< Updated upstream
 *
 *     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
=======
 * 
 *     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 
>>>>>>> Stashed changes
 * limitations under the License.
 */

package org.apache.jdo.exectck;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.CharBuffer;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;
import javax.jdo.JDOException;

public class Utilities {

  Utilities() {}

  private static final String DATE_FORMAT_NOW = "yyyyMMdd-HHmmss";

  /*
   * Return the current date/time as a String.
   */
  public static String now() {
    Calendar cal = Calendar.getInstance();
    SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
    return sdf.format(cal.getTime());
  }

  /*
   * From an array of URLs, create a classpath String suitable for use
   * as a command line argument
   */
  public static String urls2ClasspathString(List<URL> urls) {
    StringBuilder cp = new StringBuilder();

    for (URL url : urls) {
      cp.append(url.getPath());
      cp.append(File.pathSeparator);
    }
    return cp.toString();
  }

  public static String removeSubstrs(String original, String exclude) {
    String[] deleteThese = exclude.split(" ");
    String filtered = original;
    for (String sub : deleteThese) {
      filtered = filtered.replaceAll(sub.trim(), "");
    }
    return filtered.trim();
  }

  public static void printClasspath(ClassLoader loader) {
    if (loader instanceof URLClassLoader) {
      // Get the URLs
      URL[] urls = ((URLClassLoader) loader).getURLs();
      System.out.println(urls.length + " URL(s) for loader: ");
      for (URL url : urls) {
        if (url != null) {
          System.out.println("    " + url.getFile());
        }
      }
    }
  }

  public void printClasspath() {

    // Get the System Classloader
    printClasspath(ClassLoader.getSystemClassLoader());

    // Get the System Classloader
    printClasspath(Thread.currentThread().getContextClassLoader());
  }

  static String readFile(String fileName) throws IOException {
    BufferedReader reader = new BufferedReader(new FileReader(fileName));
    String line = null;
    StringBuffer stringBuf = new StringBuffer();
    String ls = System.getProperty("line.separator");
    while ((line = reader.readLine()) != null) {
      stringBuf.append(line);
      stringBuf.append(ls);
    }
    return stringBuf.toString();
  }

  InvocationResult invokeTest(List<String> command) {
    return invokeTest(new ProcessBuilder(command));
  }

  InvocationResult invokeTest(List<String> command, File directory) {
    ProcessBuilder builder = new ProcessBuilder(command);
    builder.directory(directory);
    return invokeTest(builder);
  }

  private InvocationResult invokeTest(ProcessBuilder builder) {
    InvocationResult result = new InvocationResult();
    try {
      Process proc = builder.start();
      InputStream stdout = proc.getInputStream();
      InputStream stderr = proc.getErrorStream();
      CharBuffer outBuffer = CharBuffer.allocate(1000000);
      CharBuffer errBuffer = CharBuffer.allocate(1000000);
      Thread outputThread = createReaderThread(stdout, outBuffer);
      Thread errorThread = createReaderThread(stderr, errBuffer);
      int exitValue = proc.waitFor();
      result.setExitValue(exitValue);
      errorThread.join(10000); // wait ten seconds to get stderr after process terminates
      outputThread.join(10000); // wait ten seconds to get stdout after process terminates
      result.setErrorString(errBuffer.toString());
      result.setOutputString(outBuffer.toString());
      // wait until the Enhancer command finishes
    } catch (InterruptedException ex) {
      throw new RuntimeException("InterruptedException", ex);
    } catch (IOException ex) {
      throw new RuntimeException("IOException", ex);
    } catch (JDOException jdoex) {
      jdoex.printStackTrace();
      Throwable[] throwables = jdoex.getNestedExceptions();
      System.out.println("Exception throwables of size: " + throwables.length);
      for (Throwable throwable : throwables) {
        throwable.printStackTrace();
      }
    }
    return result;
  }

  private Thread createReaderThread(final InputStream input, final CharBuffer output) {
    final Reader reader = new InputStreamReader(input);
    Thread thread =
        new Thread(
            new Runnable() {
              public void run() {
                int count = 0;
                int outputBytesRead = 0;
                try {
                  while (-1 != (outputBytesRead = reader.read(output))) {
                    count += outputBytesRead;
                  }
                } catch (IOException e) {
                  e.printStackTrace();
                } finally {
                  output.flip();
                }
              }
            });
    thread.start();
    return thread;
  }

  class InvocationResult {
    private int exitValue;
    private String errorString;
    private String outputString;

    int getExitValue() {
      return exitValue;
    }

    private void setExitValue(int exitValue) {
      this.exitValue = exitValue;
    }

    private void setErrorString(String errorString) {
      this.errorString = errorString;
    }

    String getErrorString() {
      return errorString;
    }

    private void setOutputString(String outputString) {
      this.outputString = outputString;
    }

    String getOutputString() {
      return outputString;
    }
  }
}
