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

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;

/**
 * @author Stepper
 */
public final class RepositoryComposer
{
  public static final String PROJECT = "User Storage";

  private static final String REMOVE_MARKER = "REMOVE";

  private static final Comparator<String> ALPHA_COMPARATOR = new Comparator<String>()
  {
    @Override
    public int compare(String n1, String n2)
    {
      if (n1 == null)
      {
        n1 = "";
      }

      if (n2 == null)
      {
        n2 = "";
      }

      return n2.compareTo(n1);
    }
  };

  private static final Comparator<String> VERSION_COMPARATOR = new Comparator<String>()
  {
    @Override
    public int compare(String n1, String n2)
    {
      return new Version(n2).compareTo(new Version(n1));
    }
  };

  private RepositoryComposer()
  {
  }

  public static void main(String[] args) throws Exception
  {
    File downloadsFolder = new File(args[0]).getCanonicalFile();
    String buildType = args[1];
    String buildKey = args[2];
    String buildLabel = args[3];

    String folder = buildKey;
    if (buildLabel.length() != 0)
    {
      folder += "-" + buildLabel;
    }

    File dropsFolder = new File(downloadsFolder, "drops");
    File dropTypeFolder = new File(dropsFolder, buildType);
    File dropFolder = new File(dropTypeFolder, folder);

    File updatesFolder = new File(downloadsFolder, "updates.tmp");
    File updateTypeFolder = new File(updatesFolder, buildType);

    if ("release".equals(buildType))
    {
      composeRepositories(dropTypeFolder, updateTypeFolder, VERSION_COMPARATOR, Integer.MAX_VALUE);

      boolean milestonesChanged = false;
      File milestonesFolder = new File(dropsFolder, "milestone");
      File[] children = milestonesFolder.listFiles();
      if (children != null)
      {
        for (File child : children)
        {
          if (child.isDirectory() && child.getName().contains("-" + buildLabel + "-"))
          {
            scheduleRemoval(child);
            milestonesChanged = true;
          }
        }
      }

      if (milestonesChanged)
      {
        composeMilestoneRepositories(dropsFolder, new File(updatesFolder, "milestone"));
      }
    }
    else if ("milestone".equals(buildType))
    {
      composeMilestoneRepositories(dropsFolder, updateTypeFolder);
    }
    else if ("nightly".equals(buildType))
    {
      composeRepositories(dropTypeFolder, updateTypeFolder, ALPHA_COMPARATOR, 5);
    }

    composeRepository(updatesFolder, PROJECT + " All", getComposites(updatesFolder));
    composeRepository(new File(updatesFolder, "latest"), PROJECT + " Latest", Collections.singletonList(dropFolder));
  }

  private static void composeMilestoneRepositories(File dropsFolder, File updateTypeFolder) throws IOException
  {
    File milestonesFolder = new File(dropsFolder, "milestone");
    if (!composeRepositories(milestonesFolder, updateTypeFolder, ALPHA_COMPARATOR, Integer.MAX_VALUE))
    {
      List<File> drops = new ArrayList<File>();

      File releasesFolder = new File(dropsFolder, "release");
      List<String> names = getSortedChildren(releasesFolder, VERSION_COMPARATOR);
      if (!names.isEmpty())
      {
        drops.add(new File(releasesFolder, names.get(0)));
      }

      composeRepository(updateTypeFolder, PROJECT + " Milestones", drops);
      composeRepository(new File(updateTypeFolder, "latest"), PROJECT + " Latest Milestone", drops);
    }
  }

  private static boolean composeRepositories(File dropTypeFolder, File updateTypeFolder, Comparator<String> comparator, int max) throws IOException
  {
    List<String> names = getSortedChildren(dropTypeFolder, comparator);
    if (names.isEmpty())
    {
      return false;
    }

    List<File> drops = new ArrayList<File>();
    int count = 0;

    for (String name : names)
    {
      File drop = new File(dropTypeFolder, name);
      if (++count > max)
      {
        scheduleRemoval(drop);
      }
      else
      {
        drops.add(drop);
      }
    }

    String name = dropTypeFolder.getName();
    if ("release".equals(name))
    {
      name = "Releases";
    }
    else if ("milestone".equals(name))
    {
      name = "Milestones";
    }
    else if ("nightly".equals(name))
    {
      name = "Nightly Builds";
    }

    composeRepository(updateTypeFolder, PROJECT + " " + name, drops);
    composeRepository(new File(updateTypeFolder, "latest"), PROJECT + " Latest " + name.substring(0, name.length() - 1),
        Collections.singletonList(drops.get(0)));
    return true;
  }

  private static void composeRepository(File compositeFolder, String name, List<File> drops) throws IOException
  {
    long timestamp = System.currentTimeMillis();
    writeRepository(compositeFolder, true, name, timestamp, drops);
    writeRepository(compositeFolder, false, name, timestamp, drops);
  }

  private static void writeRepository(File compositeFolder, boolean metadata, String name, long timestamp, List<File> drops) throws IOException
  {
    String entryName;
    String fileName;
    String processingInstruction;
    String type;
    if (metadata)
    {
      entryName = "compositeContent.xml";
      fileName = "compositeContent.jar";
      processingInstruction = "compositeMetadataRepository";
      type = "org.eclipse.equinox.internal.p2.metadata.repository.CompositeMetadataRepository";
    }
    else
    {
      entryName = "compositeArtifacts.xml";
      fileName = "compositeArtifacts.jar";
      processingInstruction = "compositeArtifactRepository";
      type = "org.eclipse.equinox.internal.p2.artifact.repository.CompositeArtifactRepository";
    }

    compositeFolder.mkdirs();
    File file = new File(compositeFolder, fileName);
    FileOutputStream fileOutputStream = new FileOutputStream(file);
    JarOutputStream jarOutputStream = new JarOutputStream(fileOutputStream);
    jarOutputStream.putNextEntry(new ZipEntry(entryName));

    Writer out = new OutputStreamWriter(jarOutputStream, "UTF-8");
    BufferedWriter writer = new BufferedWriter(out);

    writeLine(writer, "<?xml version='1.0' encoding='UTF-8'?>");
    writeLine(writer, "<?" + processingInstruction + " version='1.0.0'?>");
    writeLine(writer, "<repository name='" + name + "' type='" + type + "' version='1.0.0'>");
    writeLine(writer, "  <properties size='2'>");
    writeLine(writer, "    <property name='p2.timestamp' value='" + timestamp + "'/>");
    writeLine(writer, "    <property name='p2.compressed' value='false'/>");
    writeLine(writer, "  </properties>");
    writeLine(writer, "  <children size='" + drops.size() + "'>");

    for (File drop : drops)
    {
      String relativePath;
      if (drop.isAbsolute())
      {
        relativePath = getRelativePath(compositeFolder, drop);
      }
      else
      {
        relativePath = drop.getPath().replace(File.separatorChar, '/');
      }

      writeLine(writer, "    <child location='" + relativePath + "'/>");
    }

    writeLine(writer, "  </children>");
    writeLine(writer, "</repository>");
    writer.flush();

    jarOutputStream.closeEntry();
    jarOutputStream.close();
  }

  private static void writeLine(BufferedWriter writer, String line) throws IOException
  {
    writer.write(line);
    writer.write('\n');
  }

  private static String getRelativePath(File source, File target)
  {
    String targetPath = target.getAbsolutePath();
    StringBuilder builder = new StringBuilder();

    while (source != null)
    {
      String sourcePath = source.getAbsolutePath();
      if (targetPath.startsWith(sourcePath))
      {
        return builder.toString() + targetPath.substring(sourcePath.length() + 1).replace(File.separatorChar, '/');
      }

      builder.append("../");
      source = source.getParentFile();
    }

    throw new IllegalStateException();
  }

  private static List<File> getComposites(File updatesFolder)
  {
    List<File> composites = new ArrayList<File>();
    addComposite(updatesFolder, composites, "release");
    addComposite(updatesFolder, composites, "milestone");
    addComposite(updatesFolder, composites, "nightly");
    return composites;
  }

  private static void addComposite(File updatesFolder, List<File> composites, String name)
  {
    if (new File(updatesFolder, name).isDirectory())
    {
      composites.add(new File(name));
    }
  }

  private static List<String> getSortedChildren(File folder, Comparator<String> comparator)
  {
    List<String> names = new ArrayList<String>();

    File[] children = folder.listFiles();
    if (children != null)
    {
      for (File child : children)
      {
        if (child.isDirectory() && !new File(child, REMOVE_MARKER).exists())
        {
          names.add(child.getName());
        }
      }

      Collections.sort(names, comparator);
    }

    return names;
  }

  private static void scheduleRemoval(File folder) throws IOException
  {
    File marker = new File(folder, REMOVE_MARKER);
    marker.createNewFile();
  }
}
