/*
 * 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.pear.tools;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Properties;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import org.apache.uima.UIMAFramework;
import org.apache.uima.internal.util.I18nUtil;
import org.apache.uima.resource.RelativePathResolver;
import org.apache.uima.util.Level;

/**
 * Utility class to generate a pear package.
 * 
 */
public class PackageCreator {

  private static final String PEAR_MESSAGE_RESOURCE_BUNDLE = "org.apache.uima.pear.pear_messages";

  /**
   * Default method to generate a pear package. With the given information first the installation
   * descriptor is created and then the pear package is built.
   * 
   * @param componentID
   *          Specify a componentID for this component
   * 
   * @param mainComponentDesc
   *          Specify the main component descriptor path that is used to start the component. The
   *          path must be specified relative to the <code>mainComponentDir</code> parameter.
   * 
   * @param classpath
   *          Specify the classpath for this component. Use macros like <code>$main_root</code> to
   *          specify the classpath entries.
   * 
   * @param datapath
   *          Specify the datapath for this component. Use macros like <code>$main_root</code> to
   *          specify the datapath entiies.
   * 
   * @param mainComponentDir
   *          Specify the main component root directory that contains all the resources for the
   *          component. The mainComponentDir is packaged to the pear file.
   * 
   * @param targetDir
   *          Specify the target directory where the generated pear file is written to.
   * 
   * @param envVars
   *          Specify additional environment variables for the pear component. May also use macros
   *          like <code>$main_root</code> to specify the key values if necessary.
   * 
   * @throws PackageCreatorException
   *           if an error occurs while create the pear package
   */
  public static void generatePearPackage(String componentID, String mainComponentDesc,
          String classpath, String datapath, String mainComponentDir, String targetDir,
          Properties envVars) throws PackageCreatorException {

    // create installation descriptor
    createInstallDescriptor(componentID, mainComponentDesc, classpath, datapath, mainComponentDir,
            envVars);

    // packagee pear file
    createPearPackage(componentID, mainComponentDir, targetDir);
  }

  /**
   * Creates the installation descriptor with the given information and save it in the metadata
   * folder of the <code>mainComponentDir</code>.
   * 
   * @param componentID
   *          Specify a componentID for this component
   * 
   * @param mainComponentDesc
   *          Specify the main component descriptor path that is used to start the component. The
   *          path must be specified relative to the <code>mainComponentDir</code> parameter.
   * 
   * @param classpath
   *          Specify the classpath for this component. Use macros like <code>$main_root</code> to
   *          specify the classpath entries.
   * 
   * @param datapath
   *          Specify the datapath for this component. Use macros like <code>$main_root</code> to
   *          specify the datapath entiies.
   * 
   * @param mainComponentDir
   *          Specify the main component root directory that contains all the resources for the
   *          component. The mainComponentDir is packaged to the pear file.
   * 
   * @param envVars
   *          Specify additional environment variables for the pear component. May also use macros
   *          like <code>$main_root</code> to specify the key values if necessary.
   * 
   * @throws PackageCreatorException
   *           if an error occurs while creating the installation descriptor
   *           
   * @return Path to the created installation descriptor.
   */
  public static String createInstallDescriptor(String componentID, String mainComponentDesc,
          String classpath, String datapath, String mainComponentDir, Properties envVars)
          throws PackageCreatorException {

    //installation descriptor file path
    String installationDesc = null;
    
    // create new install descriptor
    InstallationDescriptor insd = new InstallationDescriptor();

    // set main component ID
    insd.setMainComponent(componentID);

    // set main component descriptor and add $main_root macro
    insd.setMainComponentDesc(addMacro(mainComponentDesc));

    // set Operation system where it was packaged
    insd.clearOSSpecs();
    insd.addOSSpec(InstallationDescriptorHandler.NAME_TAG, System.getProperty("os.name"));

    // set Java version where is was packaged
    insd.clearToolkitsSpecs();
    insd.addToolkitsSpec(InstallationDescriptorHandler.JDK_VERSION_TAG, System
            .getProperty("java.version"));

    // add classpath setting to the installation descriptor
    if (classpath != null) {
      // classpath setting should use ";" as separator
      if (classpath.indexOf(":") != -1) {
        // log warning that ";" as separator should be used.
        UIMAFramework.getLogger(PackageCreator.class).logrb(Level.WARNING, "PackageCreator",
                "createInstallDescriptor", PEAR_MESSAGE_RESOURCE_BUNDLE,
                "package_creator_classpath_not_valid_warning");
      }
      InstallationDescriptor.ActionInfo actionInfo = new InstallationDescriptor.ActionInfo(
              InstallationDescriptor.ActionInfo.SET_ENV_VARIABLE_ACT);
      actionInfo.params.put(InstallationDescriptorHandler.VAR_NAME_TAG,
              InstallationController.CLASSPATH_VAR);
      actionInfo.params.put(InstallationDescriptorHandler.VAR_VALUE_TAG, classpath);
      String commentMessage = I18nUtil.localizeMessage(PEAR_MESSAGE_RESOURCE_BUNDLE,
              "package_creator_env_setting", new Object[] { InstallationController.CLASSPATH_VAR });
      actionInfo.params.put(InstallationDescriptorHandler.COMMENTS_TAG, commentMessage);
      insd.addInstallationAction(actionInfo);

    }

    // add datapath settings to the installation descriptor
    if (datapath != null) {
      // datapath setting should use ";" as separator
      if (datapath.indexOf(":") != -1) {
        // log warning that ";" as separator should be used.
        UIMAFramework.getLogger(PackageCreator.class).logrb(Level.WARNING, "PackageCreator",
                "createInstallDescriptor", PEAR_MESSAGE_RESOURCE_BUNDLE,
                "package_creator_datapath_not_valid_warning");
      }
      InstallationDescriptor.ActionInfo actionInfo = new InstallationDescriptor.ActionInfo(
              InstallationDescriptor.ActionInfo.SET_ENV_VARIABLE_ACT);
      actionInfo.params.put(InstallationDescriptorHandler.VAR_NAME_TAG,
              RelativePathResolver.UIMA_DATAPATH_PROP);
      actionInfo.params.put(InstallationDescriptorHandler.VAR_VALUE_TAG, datapath);
      String commentMessage = I18nUtil.localizeMessage(PEAR_MESSAGE_RESOURCE_BUNDLE,
              "package_creator_env_setting",
              new Object[] { RelativePathResolver.UIMA_DATAPATH_PROP });
      actionInfo.params.put(InstallationDescriptorHandler.COMMENTS_TAG, commentMessage);
      insd.addInstallationAction(actionInfo);
    }

    // set additional environment variables
    if (envVars != null) {
      Enumeration keys = envVars.keys();
      while (keys.hasMoreElements()) {
        InstallationDescriptor.ActionInfo actionInfo = new InstallationDescriptor.ActionInfo(
                InstallationDescriptor.ActionInfo.SET_ENV_VARIABLE_ACT);
        String key = (String) keys.nextElement();
        actionInfo.params.put(InstallationDescriptorHandler.VAR_NAME_TAG, key);
        actionInfo.params
                .put(InstallationDescriptorHandler.VAR_VALUE_TAG, envVars.getProperty(key));
        String commentMessage = I18nUtil.localizeMessage(PEAR_MESSAGE_RESOURCE_BUNDLE,
                "package_creator_env_setting", new Object[] { key });
        actionInfo.params.put(InstallationDescriptorHandler.COMMENTS_TAG, commentMessage);
        insd.addInstallationAction(actionInfo);
      }
    }

    // save descriptor to metadata directory in the file system
    try {
      File metaDataDir = new File(mainComponentDir, InstallationController.PACKAGE_METADATA_DIR);
      if (!metaDataDir.exists()) {
        metaDataDir.mkdir();
      }
      File installDesc = new File(mainComponentDir, InstallationProcessor.INSD_FILE_PATH);
      InstallationDescriptorHandler.saveInstallationDescriptor(insd, installDesc);
      
      UIMAFramework.getLogger(PackageCreator.class).logrb(Level.INFO, "PackageCreator",
              "createInstallDescriptor", PEAR_MESSAGE_RESOURCE_BUNDLE,
              "package_creator_install_desc_created_info", new Object[] {installDesc});
      
      //set installation descriptor file path
      installationDesc = installDesc.getAbsolutePath();
      
    } catch (IOException ex) {
      throw new PackageCreatorException(PEAR_MESSAGE_RESOURCE_BUNDLE,
              "error_package_creator_creating_pear_package", new Object[] { componentID }, ex);
    }   
    
    return installationDesc;
  }

  /**
   * create pear package based on the given information. This method can be called if a installation
   * descriptor is already available or generated. The method will not generate the installation
   * descriptor if it is not present.
   * 
   * @param componentID
   *          Specify a componentID for this component
   * 
   * @param mainComponentDir
   *          Specify the main component root directory that contains all the resources for the
   *          component. The mainComponentDir is packaged to the pear file.
   * 
   * @param targetDir
   *          Specify the target directory where the generated pear file is written to.
   * 
   * @throws PackageCreatorException
   *           if the pear package can not be created successfully.
   * 
   * @return Retuns path absolute path to the created pear package.
   */
  public static String createPearPackage(String componentID, String mainComponentDir, String targetDir)
          throws PackageCreatorException {
    // package pear file with all data from the mainComponentDir
    ZipOutputStream zipFile;
    File pearFile;
    
    try {
      pearFile = new File(targetDir, componentID + ".pear");
      zipFile = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(pearFile)));
      File mainDir = new File(mainComponentDir);
      zipDirectory(componentID, mainDir.getAbsolutePath(), mainDir, zipFile);
      zipFile.close();
      
      UIMAFramework.getLogger(PackageCreator.class).logrb(Level.INFO, "PackageCreator",
              "createInstallDescriptor", PEAR_MESSAGE_RESOURCE_BUNDLE,
              "package_creator_pear_created_info", new Object[] {pearFile});
    } catch (FileNotFoundException ex) {
      throw new PackageCreatorException(PEAR_MESSAGE_RESOURCE_BUNDLE,
              "error_package_creator_creating_pear_package", new Object[] { componentID }, ex);
    } catch (IOException ex) {
      throw new PackageCreatorException(PEAR_MESSAGE_RESOURCE_BUNDLE,
              "error_package_creator_creating_pear_package", new Object[] { componentID }, ex);
    }
    
    return pearFile.getAbsolutePath();
  }

  /**
   * adds the $main_root/ macro as a prefix to the given string
   * 
   * @param s
   *          a String representing a relative path to the project root
   * @return The String with the macro
   */
  private static String addMacro(String s) {
    String macro = "$main_root";
    if (s == null || s.length() == 0)
      return "";
    else {
      if (s.startsWith("/") || s.startsWith("\\"))
        s = macro + s;
      else
        s = macro + File.separator + s;
      return s;
    }
  }

  /**
   * returns a postfix path of the <code>currendPath</code> based on the <code>mainDir</code>
   * prefix.
   * 
   * @param mainDir
   *          Main directory - this prefix is cut from the <code>currentPath</code>
   * 
   * @param currentPath
   *          a Path element that has the <code>mainDir</code> as prefix.
   * 
   * @return returns the postfix of the <code>currendPath</code> based on the <code>mainDir</code>
   *         prefix.
   */
  private static String getRelativePath(String mainDir, File currentPath) {
    int prefixLength = mainDir.length();
    return currentPath.getAbsolutePath().substring(prefixLength + 1);
  }

  /**
   * adds recursivly all files and directories based on the source directory to the
   * <code>ZipOutputStream</code>.
   * 
   * @param componentID
   *          componentID of the pear package.
   * 
   * @param mainDir
   *          Main directory path that should be zipped.
   * 
   * @param sourceDir
   *          Source directory that should be zipped.
   * 
   * @param zipOut
   *          zip file output stream
   * 
   * @throws PackageCreatorException
   *           if an error occurs while adding the file and directories to the zip file.
   */
  private static void zipDirectory(String componentID, String mainDir, File sourceDir,
          ZipOutputStream zipOut) throws PackageCreatorException {
    if (!sourceDir.isDirectory()) {
      throw new PackageCreatorException(PEAR_MESSAGE_RESOURCE_BUNDLE,
              "error_package_creator_invalid_directory",
              new Object[] { sourceDir.getAbsolutePath() });
    }

    try {
      // get all files and directories of the sourceDir
      String[] fileList = sourceDir.list();
      byte[] buffer = new byte[5120];

      File current = null;
      ZipEntry currentEntry = null;
      BufferedInputStream bufIn = null;

      // loop over all enties and zip them in case of files, for directories, recursivly call
      // zipDirectory()
      for (int i = 0; i < fileList.length; i++) {
        current = new File(sourceDir, fileList[i]);
        if (current.isDirectory()) {
          // if the current file is a directory, recursivly call zipDirectory()
          zipDirectory(componentID, mainDir, current, zipOut);
          continue;

        } else {
          // crate zip entry
          String path = getRelativePath(mainDir, current);
          path = path.replaceAll("\\\\", "/");
          currentEntry = new ZipEntry(path);
          zipOut.putNextEntry(currentEntry);

          // add file content to zip
          bufIn = new BufferedInputStream(new FileInputStream(current));
          int bytesRead = -1;
          while ((bytesRead = bufIn.read(buffer)) != -1) {
            zipOut.write(buffer, 0, bytesRead);
          }
          bufIn.close();
          zipOut.closeEntry();
        }
      }
    } catch (IOException ex) {
      throw new PackageCreatorException(PEAR_MESSAGE_RESOURCE_BUNDLE,
              "error_package_creator_creating_pear_package", new Object[] { componentID }, ex);
    }
  }
}
