/*
 * Copyright (c) 2014 Eike Stepper (Loehne, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *    Eike Stepper - initial API and implementation
 */
package org.eclipse.oomph.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

/**
 * @author Eike Stepper
 */
public final class ZIPUtil
{
  /**
   * @deprecated As of 3.4 use {@link #DEFAULT_BUFFER_SIZE}.
   */
  @Deprecated
  public static final int DEFALULT_BUFFER_SIZE = 4096;

  public static final int DEFAULT_BUFFER_SIZE = DEFALULT_BUFFER_SIZE;

  private static final int ORDER_KEEP = -1;

  private static final int ORDER_SWAP = 1;

  private ZIPUtil()
  {
  }

  public static void zip(ZipEntryHandler handler, File zipFile) throws IORuntimeException
  {
    final byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
    final EntryContext context = new EntryContext();

    FileOutputStream fos = IOUtil.openOutputStream(zipFile);
    ZipOutputStream zos = null;
    InputStream input = null;
    ZipEntry entry = null;

    try
    {
      zos = new ZipOutputStream(new BufferedOutputStream(fos, DEFAULT_BUFFER_SIZE));
      for (;;)
      {
        handler.handleEntry(context);
        if (context.isEmpty())
        {
          break;
        }

        try
        {
          String name = context.getName().replace(File.separatorChar, '/');
          entry = new ZipEntry(name);
          zos.putNextEntry(entry);

          if (!context.isDirectory())
          {
            input = context.getInputStream();
            if (input == null)
            {
              throw new IllegalStateException("Input is null for zip entry " + name); //$NON-NLS-1$
            }

            IOUtil.copy(input, zos, buffer);
          }
        }
        finally
        {
          IOUtil.closeSilent(input);
          if (entry != null)
          {
            zos.closeEntry();
          }

          context.reset();
        }
      }
    }
    catch (IOException ex)
    {
      throw new IORuntimeException(ex);
    }
    finally
    {
      IOUtil.closeSilent(zos);
      IOUtil.closeSilent(fos);
    }
  }

  public static void zip(File sourceFolder, boolean excludeRoot, File zipFile)
  {
    zip(new FileSystemZipHandler(sourceFolder, excludeRoot), zipFile);
  }

  public static void unzip(File zipFile, UnzipHandler handler) throws IORuntimeException
  {
    FileInputStream fis = IOUtil.openInputStream(zipFile);
    ZipInputStream zis = null;

    try
    {
      zis = new ZipInputStream(new BufferedInputStream(fis, DEFAULT_BUFFER_SIZE));

      ZipEntry entry;
      while ((entry = zis.getNextEntry()) != null)
      {
        if (entry.isDirectory())
        {
          handler.unzipDirectory(entry.getName());
        }
        else
        {
          // TODO Provide delegating InputStream that ignores close()
          handler.unzipFile(entry.getName(), zis);
        }
      }
    }
    catch (IOException ex)
    {
      throw new IORuntimeException(ex);
    }
    finally
    {
      IOUtil.closeSilent(zis);
      IOUtil.closeSilent(fis);
    }
  }

  public static void unzip(File zipFile, File targetFolder) throws IORuntimeException
  {
    unzip(zipFile, new FileSystemUnzipHandler(targetFolder, DEFAULT_BUFFER_SIZE));
  }

  /**
   * @author Eike Stepper
   */
  public interface ZipEntryHandler
  {
    public void handleEntry(EntryContext context) throws IOException;
  }

  /**
   * @author Eike Stepper
   */
  public interface UnzipHandler
  {
    public void unzipDirectory(String name) throws IOException;

    public void unzipFile(String name, InputStream zipStream) throws IOException;
  }

  /**
   * @author Eike Stepper
   */
  public static final class EntryContext
  {
    private static final String EMPTY = new String();

    private String name = EMPTY;

    private InputStream inputStream;

    private boolean directory;

    EntryContext()
    {
    }

    void reset()
    {
      name = null;
      inputStream = null;
    }

    boolean isEmpty()
    {
      return name == null;
    }

    boolean isDirectory()
    {
      return directory;
    }

    String getName()
    {
      return name;
    }

    InputStream getInputStream()
    {
      return inputStream;
    }

    public void setName(String name, boolean directory)
    {
      this.name = name + (directory ? "/" : ""); //$NON-NLS-1$ //$NON-NLS-2$
      this.directory = directory;
    }

    public void setInputStream(InputStream inputStream)
    {
      this.inputStream = inputStream;
    }
  }

  /**
   * @author Eike Stepper
   */
  public static class FileSystemZipHandler implements ZipEntryHandler
  {
    private int sourceFolderLength;

    private transient Iterator<File> files;

    public FileSystemZipHandler(File sourceFolder, boolean excludeRoot)
    {
      File root = excludeRoot ? sourceFolder : sourceFolder.getParentFile();
      sourceFolderLength = root.getAbsolutePath().length();
      if (excludeRoot)
      {
        ++sourceFolderLength;
      }

      final int baseLength = sourceFolder.getAbsolutePath().length();
      List<File> list = IOUtil.listBreadthFirst(sourceFolder);
      Collections.sort(list, new Comparator<File>()
      {
        public int compare(File f1, File f2)
        {
          String path1 = getPath(f1, baseLength);
          String path2 = getPath(f2, baseLength);
          if (path1.length() == 0)
          {
            return ORDER_KEEP;
          }

          if (path2.length() == 0)
          {
            return ORDER_SWAP;
          }

          if (f1.isDirectory())
          {
            if (f2.isDirectory())
            {
              // f1=dir, f2=dir
              if (path1.equalsIgnoreCase("/META-INF")) //$NON-NLS-1$
              {
                return ORDER_KEEP;
              }

              if (path2.equalsIgnoreCase("/META-INF")) //$NON-NLS-1$
              {
                return ORDER_SWAP;
              }

              return path1.compareTo(path2);
            }

            // f1=dir, f2=file
            if (path1.equalsIgnoreCase("/META-INF")) //$NON-NLS-1$
            {
              return ORDER_KEEP;
            }

            if (path2.equalsIgnoreCase("/META-INF/MANIFEST.MF")) //$NON-NLS-1$
            {
              return ORDER_SWAP;
            }

            return ORDER_KEEP;
          }

          if (f2.isDirectory())
          {
            // f1=file, f2=dir
            if (path2.equalsIgnoreCase("/META-INF")) //$NON-NLS-1$
            {
              return ORDER_SWAP;
            }

            if (path1.equalsIgnoreCase("/META-INF/MANIFEST.MF")) //$NON-NLS-1$
            {
              return ORDER_KEEP;
            }

            return ORDER_SWAP;
          }

          // f1=file, f2=file
          if (path1.equalsIgnoreCase("/META-INF/MANIFEST.MF")) //$NON-NLS-1$
          {
            return ORDER_KEEP;
          }

          if (path2.equalsIgnoreCase("/META-INF/MANIFEST.MF")) //$NON-NLS-1$
          {
            return ORDER_SWAP;
          }

          return path1.compareTo(path2);
        }

        private String getPath(File file, int baseLength)
        {
          String absolutePath = file.getAbsolutePath();
          String substring = absolutePath.substring(baseLength);
          String replace = substring.replace(File.separatorChar, '/');
          return replace;
        }
      });

      files = list.iterator();
      if (excludeRoot)
      {
        files.next();
      }
    }

    public void handleEntry(EntryContext context) throws IOException
    {
      if (files.hasNext())
      {
        File file = files.next();
        String name = getName(file);
        if (name.length() != 0)
        {
          context.setName(name, file.isDirectory());

          if (file.isFile())
          {
            context.setInputStream(IOUtil.openInputStream(file));
          }
        }
      }
    }

    protected String getName(File file)
    {
      return file.getAbsolutePath().substring(sourceFolderLength);
    }
  }

  /**
   * @author Eike Stepper
   */
  public static class FileSystemUnzipHandler implements UnzipHandler
  {
    private File targetFolder;

    private transient byte[] buffer;

    public FileSystemUnzipHandler(File targetFolder, int bufferSize)
    {
      this.targetFolder = targetFolder;
      buffer = new byte[bufferSize];
    }

    public FileSystemUnzipHandler(File targetFolder)
    {
      this(targetFolder, DEFAULT_BUFFER_SIZE);
    }

    public File getTargetFolder()
    {
      return targetFolder;
    }

    public void unzipDirectory(String name)
    {
      File directory = new File(targetFolder, name);
      if (!directory.exists())
      {
        directory.mkdirs();
      }
    }

    public void unzipFile(String name, InputStream zipStream)
    {
      File targetFile = new File(targetFolder, name);
      if (!targetFile.getParentFile().exists())
      {
        targetFile.getParentFile().mkdirs();
      }

      FileOutputStream out = IOUtil.openOutputStream(targetFile);

      try
      {
        IOUtil.copy(zipStream, out, buffer);
      }
      finally
      {
        IOUtil.closeSilent(out);
      }
    }
  }
}
