/*******************************************************************************
 * Copyright (c) 2009, 2013 EclipseSource 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:
 *    EclipseSource - initial API and implementation
 ******************************************************************************/
package org.eclipse.rap.ui.tests;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.pde.core.plugin.IPluginBase;
import org.eclipse.pde.internal.core.bundle.BundlePluginBase;
import org.eclipse.pde.internal.core.bundle.WorkspaceBundlePluginModel;
import org.eclipse.pde.internal.core.ibundle.IBundle;
import org.eclipse.pde.internal.core.ibundle.IBundlePluginModelBase;


@SuppressWarnings( "restriction" )
public final class TestPluginProject {

  private static final String BUNDLE_SYMBOLIC_NAME = "Bundle-SymbolicName";
  private static final String MANIFEST_MF = "META-INF/MANIFEST.MF";
  private static final String PLUGIN_XML = "plugin.xml";
  private static final String DEFAULT_SOURCE_FOLDER = "src";
  private static final String DEFAULT_OUTPUT_FOLDER = "bin";
  private static final String PLUGIN_NATURE = "org.eclipse.pde.PluginNature";
  private static int uniqueId = 0;
  private final List<Extension> extensions;
  private final IProject project;
  private final IJavaProject javaProject;

  public TestPluginProject() throws CoreException {
    this( "test.project." + uniqueId );
    uniqueId++ ;
  }

  public TestPluginProject( String name ) throws CoreException {
    extensions = new ArrayList<Extension>();
    project = createProject( name );
    project.open( new NullProgressMonitor() );
    addNature( JavaCore.NATURE_ID );
    javaProject = createJavaProjectLayout();
    addNature( PLUGIN_NATURE );
    createManifest();
    waitForAutoBuild();
  }

  public String getName() {
    return project.getName();
  }

  public IJavaProject getJavaProject() {
    return javaProject;
  }

  public void createExtension( String point, String element, Map<String, String> attributes )
    throws CoreException
  {
    extensions.add( new Extension( point, element, attributes, null ) );
    String contents = createPluginXmlContents();
    savePluginXml( contents.toString() );
    ensureSingletonBundle();
  }

  public void createExtensionWithExtensionId( String point,
                                              String element,
                                              Map<String, String> attributes,
                                              String id ) throws CoreException
  {
    extensions.add( new Extension( point, element, attributes, id ) );
    String contents = createPluginXmlContents();
    savePluginXml( contents.toString() );
    ensureSingletonBundle();
  }

  public void delete() throws CoreException {
    project.delete( true, true, new NullProgressMonitor() );
  }

  // ////////////////////////
  // Project creation helper
  private IJavaProject createJavaProjectLayout() throws CoreException {
    project.open( new NullProgressMonitor() );
    IJavaProject result = JavaCore.create( project );
    IFolder srcFolder = project.getFolder( DEFAULT_SOURCE_FOLDER );
    if( !srcFolder.exists() ) {
      srcFolder.create( false, true, new NullProgressMonitor() );
    }
    IPath srcPath = srcFolder.getFullPath();
    IClasspathEntry srcEntry = JavaCore.newSourceEntry( srcPath );
    IPath jrePath = JavaRuntime.getDefaultJREContainerEntry().getPath();
    IClasspathEntry jreEntry = JavaCore.newContainerEntry( jrePath );
    IPath binPath = project.getFullPath().append( DEFAULT_OUTPUT_FOLDER );
    IClasspathEntry[] cpes = new IClasspathEntry[] { srcEntry, jreEntry };
    result.setRawClasspath( cpes, binPath, new NullProgressMonitor() );
    return result;
  }

  private void createManifest() {
    IFile pluginFile = project.getFile( PLUGIN_XML );
    IFile bundleFile = project.getFile( MANIFEST_MF );
    IBundlePluginModelBase model = new WorkspaceBundlePluginModel( bundleFile, pluginFile );
    IPluginBase plugin = model.getPluginBase();
    IBundle bundle = ( ( BundlePluginBase )plugin ).getBundle();
    bundle.setHeader( BUNDLE_SYMBOLIC_NAME, project.getName() );
    bundle.setHeader( "Bundle-Version", "1.0.0" ); //$NON-NLS-1$ //$NON-NLS-2$
    bundle.setHeader( "Bundle-ManifestVersion", "2" ); //$NON-NLS-1$ //$NON-NLS-2$
    bundle.setHeader( "Bundle-ActivationPolicy", "lazy" ); //$NON-NLS-1$ //$NON-NLS-2$
    bundle.setHeader( "Bundle-RequiredExecutionEnvironment", "J2SE-1.4" ); //$NON-NLS-1$ //$NON-NLS-2$
    model.save();
  }

  private void addNature( String nature ) throws CoreException {
    IProjectDescription description = project.getDescription();
    String[] natures = description.getNatureIds();
    String[] newNatures = new String[ natures.length + 1 ];
    System.arraycopy( natures, 0, newNatures, 0, natures.length );
    newNatures[ natures.length ] = nature;
    description.setNatureIds( newNatures );
    project.setDescription( description, new NullProgressMonitor() );
  }

  private static IProject createProject( String name ) throws CoreException {
    IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
    IProject result = root.getProject( name );
    result.create( new NullProgressMonitor() );
    return result;
  }

  // /////////////////////////////
  // plugin.xml generation helper
  private String createPluginXmlContents() {
    StringBuffer result = new StringBuffer();
    result.append( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" );
    result.append( "<?eclipse version=\"3.4\"?>\n" );
    result.append( "<plugin>\n" );
    Iterator iter = extensions.iterator();
    while( iter.hasNext() ) {
      Extension extension = ( Extension )iter.next();
      result.append( extension.toXml() );
    }
    result.append( "</plugin>" );
    return result.toString();
  }

  private void savePluginXml( String contents ) throws CoreException {
    IFile pluginXml = project.getFile( PLUGIN_XML );
    InputStream stream = toUtf8Stream( contents );
    if( !pluginXml.exists() ) {
      pluginXml.create( stream, true, new NullProgressMonitor() );
    } else {
      pluginXml.setContents( stream, false, false, new NullProgressMonitor() );
    }
    waitForAutoBuild();
  }

  private static ByteArrayInputStream toUtf8Stream( String string ) {
    try {
      return new ByteArrayInputStream( string.getBytes( "UTF-8" ) ); //$NON-NLS-1$
    } catch( UnsupportedEncodingException e ) {
      throw new RuntimeException( "Failed to encode string to UTF-8.", e ); //$NON-NLS-1$
    }
  }

  private void ensureSingletonBundle() {
    IFile pluginFile = project.getFile( PLUGIN_XML );
    IFile bundleFile = project.getFile( MANIFEST_MF );
    IBundlePluginModelBase model = new WorkspaceBundlePluginModel( bundleFile, pluginFile );
    IPluginBase plugin = model.getPluginBase();
    IBundle bundle = ( ( BundlePluginBase )plugin ).getBundle();
    String symbolicName = bundle.getHeader( BUNDLE_SYMBOLIC_NAME );
    if( !symbolicName.endsWith( "singleton:=true" ) ) {
      symbolicName += "; singleton:=true";
      bundle.setHeader( BUNDLE_SYMBOLIC_NAME, symbolicName );
      model.save();
    }
  }

  // ////////////////
  // helping methods
  private static void waitForAutoBuild() throws CoreException {
    try {
      NullProgressMonitor monitor = new NullProgressMonitor();
      Job.getJobManager().join( ResourcesPlugin.FAMILY_AUTO_BUILD, monitor );
    } catch( OperationCanceledException e ) {
      handleException( "waitForAutoBuild failed", e );
    } catch( InterruptedException e ) {
      //handleException( "waitForAutoBuild failed", e );
    }
  }

  private static void handleException( String msg, Throwable throwable )
    throws CoreException
  {
    IStatus status = new Status( IStatus.ERROR, Fixture.PLUGIN_ID, msg, throwable );
    throw new CoreException( status );
  }

  // ///////////////
  // helper classes
  private static final class Extension {

    private final String point;
    private final String element;
    private final Map<String, String> attributes;
    private final String id;

    private Extension( String point, String element, Map<String, String> attributes, String id ) {
      this.point = point;
      this.element = element;
      this.attributes = new HashMap<String, String>();
      this.id = id;
      if( attributes != null ) {
        this.attributes.putAll( attributes );
      }
    }

    private String toXml() {
      StringBuffer result = new StringBuffer();
      result.append( "<extension" );
      if( id != null ) {
        result.append( " id=\"" + id + "\"" );
      }
      result.append( " point=\"" );
      result.append( point );
      result.append( "\">\n" );
      result.append( "  <" );
      result.append( element );
      result.append( "\n" );
      Iterator iter = attributes.keySet().iterator();
      while( iter.hasNext() ) {
        String name = ( String )iter.next();
        result.append( "    " );
        result.append( name );
        result.append( "=\"" );
        result.append( attributes.get( name ) );
        result.append( "\"" );
        if( iter.hasNext() ) {
          result.append( "\n" );
        }
      }
      result.append( ">\n" );
      result.append( "  </" );
      result.append( element );
      result.append( ">\n" );
      result.append( "</extension>\n" );
      return result.toString();
    }
  }

}
