/*
 * 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.oodt.cas.product.data;

//OODT imports
import org.apache.oodt.cas.filemgr.structs.Product;
import org.apache.oodt.cas.filemgr.structs.ProductPage;
import org.apache.oodt.cas.filemgr.structs.ProductType;
import org.apache.oodt.cas.filemgr.structs.exceptions.ConnectionException;
import org.apache.oodt.cas.filemgr.system.XmlRpcFileManagerClient;
import org.apache.oodt.cas.metadata.Metadata;
import org.apache.oodt.cas.metadata.util.PathUtils;

//JDK imports
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Delivers back entire {@link ProductType}s (or <code>Dataset</code>s) as
 * zipped up packages.
 * 
 * @author mattmann
 * @version $Revision$
 */
public class DatasetDeliveryServlet extends HttpServlet implements
    DataDeliveryKeys {

  /* our log stream */
  private static final Logger LOG = Logger
      .getLogger(DatasetDeliveryServlet.class.getName());

  /* serial version UID */
  private static final long serialVersionUID = -6692665690674186105L;

  /* our file manager client */
  private XmlRpcFileManagerClient client;

  /* the working dir in which to create huge zip files */
  private String workingDirPath;

  /* indicates the product has been zipped up already */
  private final static String ALREADY_ZIPPED = "00ga";

  /*
   * (non-Javadoc)
   * 
   * @see
   * javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest,
   * javax.servlet.http.HttpServletResponse)
   */
  protected void doGet(HttpServletRequest req, HttpServletResponse res)
      throws ServletException, IOException {
    doPut(req, res);
  }

  /**
   * 
   * Method requires a single parameter, <code>typeID</code>, specifying a valid
   * {@link ProductType} within the filemgr. All {@link Product}s associated
   * with the given <code>typeID</code> are packaged up (as zip files), and then
   * aggregated and zipped and delivered as an entire collection called a
   * <code>Dataset</code>.
   * 
   * @param req
   *          Servlet request.
   * @param res
   *          Servlet response
   * @throws ServletException
   *           If any error occurs.
   * @throws IOException
   *           If an I/O error occurs.
   */
  protected void doPut(HttpServletRequest req, HttpServletResponse res)
      throws ServletException, IOException {

    String typeID = req.getParameter("typeID");
    ProductType type = null;

    if (typeID == null) {
      throw new IllegalArgumentException("No typeID parameter specified!");
    }

    try {
      type = client.getProductTypeById(typeID);
    } catch (Exception e) {
      throw new ServletException("Unable to deduce product type: [" + typeID
          + "]: Message: " + e.getMessage());
    }

    // create a temporary product dir: we'll use working dir + typeName
    String productDirPath = workingDirPath + type.getName();
    if (!new File(productDirPath).mkdirs()) {
      LOG.log(Level.WARNING,
          "mkdirs returned false for temporary dataset dir: [" + productDirPath
              + "]: errors may follow");
    }

    // use the pagination API to iterate over each product
    // for each product, zip it up
    // after you zip up all products then create the dataset zip

    ProductPage page = null;

    try {
      page = client.getFirstPage(type);
      if (page == null
          || (page != null && page.getPageProducts() == null)
          || (page != null && page.getPageProducts() != null && page
              .getPageProducts().size() == 0)) {
        throw new ServletException("No products for dataset: ["
            + type.getName() + "]");
      }

      Map productHash = new HashMap();

      do {
        for (Iterator i = page.getPageProducts().iterator(); i.hasNext();) {
          Product product = (Product) i.next();
          if (alreadyZipped(product, productHash)) {
            continue;
          }

          Metadata metadata = null;
          product.setProductReferences(client.getProductReferences(product));
          metadata = client.getMetadata(product);
          DataUtils.createProductZipFile(product, metadata, productDirPath);
          productHash.put(product.getProductName(), ALREADY_ZIPPED);
        }

        page = client.getNextPage(type, page);

      } while ((page != null && !page.isLastPage())
          && (page.getPageProducts() != null && page.getPageProducts().size() > 0));
    } catch (Exception e) {
      e.printStackTrace();
      throw new ServletException(e.getMessage());
    }

    // now that all product zips have been created, create the dataset
    // zip
    String datasetZipFilePath = null;
    File datasetZipFile = null;
    InputStream in = null;
    OutputStream o2 = null;

    try {
      datasetZipFilePath = DataUtils.createDatasetZipFile(type, productDirPath);

      datasetZipFile = new File(datasetZipFilePath);
      String datasetZipFileName = datasetZipFile.getName();

      res.addHeader(CONTENT_DISPOSITION_HDR, "attachment; filename=\""
          + datasetZipFileName + "\"");

      // add the content length for the zip file size
      res.addHeader(CONTENT_LENGTH_HDR, String.valueOf(new File(
          datasetZipFilePath).length()));

      // now we need to read the zip file in, and write it to the output
      // stream
      in = new FileInputStream(datasetZipFile);

      // Call java.io.File.delete() on the file, while still open.
      if (!datasetZipFile.delete()) {
        throw new RuntimeException("Unable to delete streaming file: ["
            + datasetZipFile.getAbsolutePath() + "] while delivering!");
      }

      // 3. Deliver the data.
      o2 = res.getOutputStream();
      byte[] buf = new byte[512];
      int n;
      while ((n = in.read(buf)) != -1)
        o2.write(buf, 0, n);

    } catch (Exception e) {
      e.printStackTrace();
      LOG.log(Level.WARNING, "Exception delivering dataset: Message: "
          + e.getMessage());
    } finally {
      if (in != null) {
        try {
          in.close();
        } catch (Exception ignore) {
        }

        in = null;
      }

      if (o2 != null) {
        try {
          o2.close();
        } catch (Exception ignore) {
        }

        o2 = null;
      }

      // now try and remove the tmp working directory for the
      // dataset zip
      if (datasetZipFile != null) {
        datasetZipFile.getParentFile().delete();
      }
      datasetZipFile = null;
    }

  }

  /*
   * (non-Javadoc)
   * 
   * @see javax.servlet.GenericServlet#init(javax.servlet.ServletConfig)
   */
  public void init(ServletConfig config) throws ServletException {
    super.init(config);

    try {
      String fileMgrURL = null;
      try {
        fileMgrURL = PathUtils.replaceEnvVariables(config.getServletContext().getInitParameter(
            "filemgr.url") );
      } catch (Exception e) {
        throw new ServletException("Failed to get filemgr url : " + e.getMessage(), e);
      }      
      if (fileMgrURL == null)
        fileMgrURL = "http://localhost:9000";
      client = new XmlRpcFileManagerClient(new URL(fileMgrURL));
    } catch (MalformedURLException ex) {
      throw new ServletException(ex);
    } catch (ConnectionException ex) {
      throw new ServletException(ex);
    }

    workingDirPath = config.getServletContext().getInitParameter(
        "filemgr.working.dir");

    // need the working dir to be specified, else throw exception
    if (workingDirPath == null) {
      throw new ServletException("no servlet working dir path specified!");
    } else {
      // clean it
      this.workingDirPath += this.workingDirPath.endsWith("/") ? "" : "/";
    }

  }

  private boolean alreadyZipped(Product p, Map hash) {
    return hash.containsKey(p.getProductName());
  }

}
