/*
 * Copyright (c) 2016 Ed Merks 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:
 *    Ed Merks - initial API and implementation
 */
package org.eclipse.oomph.setup.internal.core;

import org.eclipse.oomph.base.Annotation;
import org.eclipse.oomph.base.util.EAnnotations;
import org.eclipse.oomph.setup.AnnotationConstants;
import org.eclipse.oomph.setup.Configuration;
import org.eclipse.oomph.setup.Installation;
import org.eclipse.oomph.setup.ProductVersion;
import org.eclipse.oomph.setup.Project;
import org.eclipse.oomph.setup.Scope;
import org.eclipse.oomph.setup.SetupTask;
import org.eclipse.oomph.setup.SetupTaskContainer;
import org.eclipse.oomph.setup.Stream;
import org.eclipse.oomph.setup.Workspace;
import org.eclipse.oomph.setup.internal.core.util.ECFURIHandlerImpl;
import org.eclipse.oomph.setup.internal.core.util.ECFURIHandlerImpl.CacheHandling;
import org.eclipse.oomph.setup.internal.core.util.ResourceMirror;
import org.eclipse.oomph.setup.internal.core.util.SetupCoreUtil;
import org.eclipse.oomph.util.CollectionUtil;
import org.eclipse.oomph.util.IORuntimeException;
import org.eclipse.oomph.util.IOUtil;
import org.eclipse.oomph.util.OS;
import org.eclipse.oomph.util.StringUtil;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.emf.ecore.resource.URIHandler;
import org.eclipse.emf.ecore.util.EcoreUtil;

import org.eclipse.equinox.app.IApplication;
import org.eclipse.equinox.app.IApplicationContext;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/**
 * @author Ed Merks
 */
public class SetupArchiver implements IApplication
{
  public Object start(IApplicationContext context)
  {
    String[] arguments = (String[])context.getArguments().get(IApplicationContext.APPLICATION_ARGS);

    // The default target file is the cache location of the local setup archive.
    final ResourceSet resourceSet = SetupCoreUtil.createResourceSet();
    final URIConverter uriConverter = resourceSet.getURIConverter();

    for (ListIterator<URIHandler> it = uriConverter.getURIHandlers().listIterator(); it.hasNext();)
    {
      // Create a delegating handling for ECFURIHandler...
      // The GITC is serving bytes that randomly have trailing garbage.
      final URIHandler uriHandler = it.next();
      if (uriHandler instanceof ECFURIHandlerImpl)
      {
        it.set(new URIHandler()
        {
          public void setAttributes(URI uri, Map<String, ?> attributes, Map<?, ?> options) throws IOException
          {
            uriHandler.setAttributes(uri, attributes, options);
          }

          public Map<String, ?> getAttributes(URI uri, Map<?, ?> options)
          {
            return uriHandler.getAttributes(uri, options);
          }

          public boolean exists(URI uri, Map<?, ?> options)
          {
            return uriHandler.exists(uri, options);
          }

          public void delete(URI uri, Map<?, ?> options) throws IOException
          {
            uriHandler.delete(uri, options);
          }

          public OutputStream createOutputStream(URI uri, Map<?, ?> options) throws IOException
          {
            return uriHandler.createOutputStream(uri, options);
          }

          public InputStream createInputStream(URI uri, Map<?, ?> options) throws IOException
          {
            InputStream result = uriHandler.createInputStream(uri, options);
            try
            {
              // Copy the bytes out of the stream.
              ByteArrayOutputStream initialOut = new ByteArrayOutputStream();
              IOUtil.copy(result, initialOut);
              byte[] initialBytes = initialOut.toByteArray();

              // Create yet another stream.
              result = uriHandler.createInputStream(uri, options);

              // Read this one too, and check if the bytes are the same.
              ByteArrayOutputStream secondaryOut = new ByteArrayOutputStream();
              IOUtil.copy(result, secondaryOut);
              byte[] secondaryBytes = secondaryOut.toByteArray();
              if (Arrays.equals(initialBytes, secondaryBytes))
              {
                // If so we can return a stream for those bytes.
                return new ByteArrayInputStream(initialBytes);
              }
              else
              {
                // If not, we fail early so we don't even try to load the resource.
                // This way we don't end up with a resource with what's likely to be bad contents.
                // At least for XML parsing fails, but with images, we can't check if the image is valid.
                throw new IOException("The server is delivering inconsistent results for " + uri);
              }
            }
            catch (IORuntimeException ex)
            {
              throw new IOException(ex);
            }
          }

          public Map<String, ?> contentDescription(URI uri, Map<?, ?> options) throws IOException
          {
            return uriHandler.contentDescription(uri, options);
          }

          public boolean canHandle(URI uri)
          {
            return uriHandler.canHandle(uri);
          }
        });
      }
    }

    URI archiveLocation = uriConverter.normalize(SetupContext.INDEX_SETUP_ARCHIVE_LOCATION_URI);
    File file = new File(ECFURIHandlerImpl.getCacheFile(archiveLocation).toFileString());

    Set<URI> uris = new LinkedHashSet<URI>();
    uris.add(SetupContext.INDEX_SETUP_URI);

    boolean expectURIs = false;
    for (int i = 0; i < arguments.length; ++i)
    {
      String argument = arguments[i];
      if (argument.startsWith("-"))
      {
        expectURIs = false;
      }

      if (expectURIs)
      {
        uris.add(URI.createURI(argument));
      }
      else if ("-target".equals(argument))
      {
        file = new File(arguments[++i]);
      }
      else if ("-uris".equals(argument))
      {
        expectURIs = true;
      }
    }

    String url = file.getAbsolutePath();
    if (url.startsWith("/home/data/httpd/"))
    {
      url = "http://" + url.substring("/home/data/httpd/".length());
      System.out.println();
      System.out.println("--> " + url);
      System.out.println();
    }

    Set<String> entryNames = new HashSet<String>();
    long lastModified = file.lastModified();
    File temp = new File(file.toString() + ".tmp");
    URI outputLocation;

    if (lastModified == 0)
    {
      outputLocation = URI.createURI("archive:" + URI.createFileURI(file.toString()) + "!/");
    }
    else
    {
      IOUtil.copyFile(file, temp);

      if (!temp.setLastModified(lastModified))
      {
        throw new IORuntimeException("Could not set timestamp of " + temp);
      }

      outputLocation = URI.createURI("archive:" + URI.createFileURI(temp.toString()) + "!/");

      ZipFile zipFile = null;
      try
      {
        zipFile = new ZipFile(temp);
        for (Enumeration<? extends ZipEntry> entries = zipFile.entries(); entries.hasMoreElements();)
        {
          ZipEntry zipEntry = entries.nextElement();

          String name = zipEntry.getName();
          entryNames.add(name);

          URI path = URI.createURI(name);
          URI uri = URI.createURI(path.segment(0) + ":" + "//" + path.segment(1));
          for (int i = 2, length = path.segmentCount(); i < length; ++i)
          {
            uri = uri.appendSegment(path.segment(i));
          }

          URI archiveEntry = URI.createURI("archive:" + URI.createFileURI(file.toString()) + "!/" + path);

          System.out.println("Previously mirrored " + uri + " -> " + archiveEntry);
        }
      }
      catch (IOException ex)
      {
        if (!file.delete())
        {
          throw new IORuntimeException("Could delete bad version of " + file);
        }

        lastModified = 0;
        outputLocation = URI.createURI("archive:" + URI.createFileURI(file.toString()) + "!/");
      }
      finally
      {
        try
        {
          if (zipFile != null)
          {
            zipFile.close();
          }
        }
        catch (IOException ex)
        {
          ex.printStackTrace();
        }
      }
    }

    resourceSet.getLoadOptions().put(ECFURIHandlerImpl.OPTION_CACHE_HANDLING, CacheHandling.CACHE_IGNORE);

    ResourceMirror resourceMirror = new ResourceMirror.WithProductImages(resourceSet)
    {
      @Override
      protected void visit(EObject eObject)
      {
        if (eObject instanceof EClass)
        {
          EClass eClass = (EClass)eObject;
          if (!eClass.isAbstract())
          {
            final URI imageURI = EAnnotations.getImageURI(eClass);
            if (imageURI != null && resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().containsKey(imageURI.fileExtension()))
            {
              schedule(imageURI, true);
            }
          }
        }

        super.visit(eObject);
      }
    };

    resourceMirror.perform(uris);
    resourceMirror.dispose();
    EcoreUtil.resolveAll(resourceSet);

    ECFURIHandlerImpl.clearExpectedETags();

    Map<URI, URI> uriMap = uriConverter.getURIMap();
    Map<Object, Object> options = new HashMap<Object, Object>();
    if (lastModified != 0)
    {
      options.put(Resource.OPTION_SAVE_ONLY_IF_CHANGED, Resource.OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER);
      // options.put(Resource.OPTION_LINE_DELIMITER, "\n");
    }

    // Remove any folder redirections that might be in place for the location of the setups folder and folders under that.
    for (Iterator<URI> it = uriMap.keySet().iterator(); it.hasNext();)
    {
      URI uri = it.next();
      URI deresolvedURI = uri.deresolve(SetupContext.INDEX_ROOT_LOCATION_URI);
      if (deresolvedURI.isRelative())
      {
        it.remove();
      }
    }

    uriMap.remove(SetupContext.INDEX_ROOT_LOCATION_URI);

    // If Ecore models fail to load correct, the org.eclipse.setup will resolve the package proxies incorrectly and will look changed.
    // We don't want that, so terminate early.
    boolean hasEcoreFailures = false;
    for (Resource resource : resourceSet.getResources())
    {
      URI uri = resource.getURI();
      URI normalizedURI = uriConverter.normalize(uri);
      if ("ecore".equals(uri.fileExtension()) && (resource.getContents().isEmpty() || !resource.getErrors().isEmpty()))
      {
        System.err.println("FAILED to load " + normalizedURI);
        printDiagnostics(resource.getErrors());
        System.err.println("Aborting");
        hasEcoreFailures = true;
        break;
      }
    }

    if (!hasEcoreFailures)
    {
      boolean hasFailures = false;
      Map<Project, Set<Configuration>> configurations = new LinkedHashMap<Project, Set<Configuration>>();

      for (Resource resource : resourceSet.getResources())
      {
        URI uri = resource.getURI();

        URI normalizedURI = uriConverter.normalize(uri);
        String scheme = normalizedURI.scheme();
        if (normalizedURI.query() == null && ("http".equals(scheme) || "https".equals(scheme)))
        {
          URI path = URI.createURI(scheme);
          path = path.appendSegment(normalizedURI.authority());
          path = path.appendSegments(normalizedURI.segments());
          System.out.println("Mirroring " + normalizedURI);

          URI output = path.resolve(outputLocation);
          entryNames.remove(path.toString());
          uriMap.put(uri, output);

          if (resource.getContents().isEmpty() || !resource.getErrors().isEmpty())
          {
            System.err.println("FAILED to load " + normalizedURI);
            printDiagnostics(resource.getErrors());
            hasFailures = true;
          }
          else
          {
            try
            {
              long before = resource.getTimeStamp();
              resource.save(options);
              long after = resource.getTimeStamp();

              if (after - before > 0)
              {
                System.err.println("CHANGED! " + normalizedURI);
              }
            }
            catch (IOException ex)
            {
              System.err.println("FAILED to save " + normalizedURI);
              ex.printStackTrace();
            }

            collectConfigurations(resource, configurations);
          }
        }
        else
        {
          System.out.println("Ignoring  " + normalizedURI);
        }
      }

      if (hasFailures)
      {
        System.err.println("There were failures so no entries will be deleted from the archive");
      }
      else
      {
        for (String entryName : entryNames)
        {
          URI archiveEntry = URI.createURI(outputLocation + entryName);

          try
          {
            uriConverter.delete(archiveEntry, null);
          }
          catch (IOException ex)
          {
            ex.printStackTrace();
          }
        }
      }

      createConfigurationPage(configurations);
    }

    long finalLastModified = lastModified == 0 ? file.lastModified() : temp.lastModified();
    if (lastModified != finalLastModified)
    {
      if (OS.INSTANCE.isWin())
      {
        if (lastModified != 0 && !file.delete())
        {
          System.err.println("Could not delete " + file);
        }
      }

      if (lastModified == 0)
      {
        if (isDamaged(file))
        {
          System.err.println("The resulting archive is damaged. Deleting " + file);
          file.delete();
        }
        else
        {
          System.out.println("Successfully created " + file);
        }
      }
      else if (isDamaged(temp))
      {
        System.err.println("The resulting archive is damaged so the old one will be retained. Deleting " + file);
        temp.delete();
      }
      else
      {
        File backup = new File(file.getParentFile(), file.getName() + ".bak");
        try
        {
          IOUtil.copyFile(temp, backup);
        }
        catch (Throwable throwable)
        {
          System.err.println("Could not create backup " + backup);
        }

        if (temp.renameTo(file))
        {
          System.out.println("Successful updates for " + file);
        }
        else
        {
          System.err.println("Could not rename " + temp + " to " + file);
        }
      }
    }
    else
    {
      System.out.println("No updates for " + file);
      if (!temp.delete())
      {
        System.err.println("Could not delete " + temp);
      }
    }

    return null;
  }

  private boolean isDamaged(File file)
  {
    if (file == null || !file.exists())
    {
      return true;
    }

    if (file.isFile())
    {
      ZipFile zipFile = null;

      try
      {
        zipFile = new ZipFile(file);
        Enumeration<? extends ZipEntry> entries = zipFile.entries();
        if (!entries.hasMoreElements())
        {
          return true;
        }

        do
        {
          ZipEntry entry = entries.nextElement();

          entry.getName();
          entry.getCompressedSize();
          entry.getCrc();

          InputStream inputStream = null;

          try
          {
            inputStream = zipFile.getInputStream(entry);
            if (inputStream == null)
            {
              return true;
            }
          }
          finally
          {
            IOUtil.close(inputStream);
          }
        } while (entries.hasMoreElements());
      }
      catch (Exception ex)
      {
        return true;
      }
      finally
      {
        try
        {
          if (zipFile != null)
          {
            zipFile.close();
          }
        }
        catch (IOException ex)
        {
          throw new IORuntimeException(ex);
        }
      }
    }

    return false;
  }

  private void printDiagnostics(List<Resource.Diagnostic> diagnostics)
  {
    for (Resource.Diagnostic diagnostic : diagnostics)
    {
      System.err.println("  ERROR: " + diagnostic.getMessage() + " " + diagnostic.getLine() + " " + diagnostic.getLine() + " " + diagnostic.getColumn());
    }
  }

  private void collectConfigurations(Resource resource, Map<Project, Set<Configuration>> configurations)
  {
    EObject root = resource.getContents().get(0);
    if (root instanceof Configuration)
    {
      Configuration configuration = (Configuration)root;
      Workspace workspace = configuration.getWorkspace();
      if (workspace != null)
      {
        for (Stream stream : workspace.getStreams())
        {
          Project project = stream.getProject();
          CollectionUtil.add(configurations, project, configuration);
        }
      }
    }
  }

  private void createConfigurationPage(Map<Project, Set<Configuration>> configurations)
  {
    for (Map.Entry<Project, Set<Configuration>> entry : configurations.entrySet())
    {
      Project project = entry.getKey();
      System.out.println(getLabel(project));

      for (Configuration configuration : entry.getValue())
      {
        System.out.println("  Configuration: " + EcoreUtil.getURI(configuration));

        Installation installation = configuration.getInstallation();
        if (installation != null)
        {
          System.out.println("    " + getLabel(installation) + getDescription(installation));

          ProductVersion productVersion = installation.getProductVersion();
          if (productVersion != null)
          {
            System.out.println("      " + getLabel(productVersion.getProduct()) + " (" + getLabel(productVersion) + ")" + getDescription(productVersion));
          }
        }

        Workspace workspace = configuration.getWorkspace();
        System.out.println("    " + getLabel(workspace) + getDescription(workspace));

        Set<String> gitRepos = new HashSet<String>();
        for (Stream stream : workspace.getStreams())
        {
          System.out.println("      " + getLabel(stream.getProject()) + " (" + getLabel(stream) + ")" + getDescription(stream));
          findGitRepos(stream, gitRepos);
        }

        for (String gitRepo : gitRepos)
        {
          System.out.println("        " + gitRepo);
        }
      }
    }
  }

  private void findGitRepos(Scope scope, Set<String> gitRepos)
  {
    findGitRepos(scope.getSetupTasks(), gitRepos);

    Scope parentScope = scope.getParentScope();
    if (parentScope instanceof Project)
    {
      findGitRepos(parentScope, gitRepos);
    }
  }

  private void findGitRepos(EList<SetupTask> setupTasks, Set<String> gitRepos)
  {
    for (SetupTask setupTask : setupTasks)
    {
      EClass eClass = setupTask.eClass();

      if ("GitCloneTask".equals(eClass.getName()))
      {
        String remoteURI = (String)setupTask.eGet(eClass.getEStructuralFeature("remoteURI"));

        Annotation annotation = setupTask.getAnnotation(AnnotationConstants.ANNOTATION_INDUCED_CHOICES);
        if (annotation != null)
        {
          int xxx;
        }

        gitRepos.add(remoteURI);
      }

      if (setupTask instanceof SetupTaskContainer)
      {
        SetupTaskContainer container = (SetupTaskContainer)setupTask;
        findGitRepos(container.getSetupTasks(), gitRepos);
      }
    }
  }

  private String getLabel(Scope scope)
  {
    if (scope instanceof Project)
    {
      Project parentProject = ((Project)scope).getParentProject();
      if (parentProject != null)
      {
        return getLabel(parentProject) + " - " + SetupCoreUtil.getLabel(scope);
      }
    }

    return SetupCoreUtil.getLabel(scope);
  }

  private String getDescription(Scope scope)
  {
    String description = scope.getDescription();
    if (!StringUtil.isEmpty(description))
    {
      return " --> " + description;
    }

    return "";
  }

  public void stop()
  {
  }
}
