/*******************************************************************************
 * Copyright (c) 2010 BSI Business Systems Integration AG.
 * 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:
 *     BSI Business Systems Integration AG - initial API and implementation
 ******************************************************************************/
package org.eclipse.scout.sdk.operation.outline;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jface.text.Document;
import org.eclipse.scout.commons.CollectionUtility;
import org.eclipse.scout.nls.sdk.model.INlsEntry;
import org.eclipse.scout.sdk.extensions.runtime.classes.IRuntimeClasses;
import org.eclipse.scout.sdk.extensions.runtime.classes.RuntimeClasses;
import org.eclipse.scout.sdk.internal.ScoutSdk;
import org.eclipse.scout.sdk.operation.jdt.JavaElementFormatOperation;
import org.eclipse.scout.sdk.operation.jdt.method.MethodNewOperation;
import org.eclipse.scout.sdk.operation.jdt.method.MethodUpdateContentOperation;
import org.eclipse.scout.sdk.operation.jdt.packageFragment.ExportPolicy;
import org.eclipse.scout.sdk.operation.jdt.type.OrderedInnerTypeNewOperation;
import org.eclipse.scout.sdk.operation.jdt.type.PrimaryTypeNewOperation;
import org.eclipse.scout.sdk.sourcebuilder.SortedMemberKeyFactory;
import org.eclipse.scout.sdk.sourcebuilder.comment.CommentSourceBuilderFactory;
import org.eclipse.scout.sdk.sourcebuilder.method.IMethodBodySourceBuilder;
import org.eclipse.scout.sdk.sourcebuilder.method.IMethodSourceBuilder;
import org.eclipse.scout.sdk.sourcebuilder.method.MethodBodySourceBuilderFactory;
import org.eclipse.scout.sdk.sourcebuilder.method.MethodSourceBuilderFactory;
import org.eclipse.scout.sdk.util.SdkProperties;
import org.eclipse.scout.sdk.util.signature.IImportValidator;
import org.eclipse.scout.sdk.util.signature.SignatureCache;
import org.eclipse.scout.sdk.util.type.TypeUtility;
import org.eclipse.scout.sdk.util.typecache.ITypeHierarchy;
import org.eclipse.scout.sdk.util.typecache.IWorkingCopyManager;
import org.eclipse.scout.sdk.workspace.type.IStructuredType;
import org.eclipse.scout.sdk.workspace.type.ScoutTypeUtility;
import org.eclipse.text.edits.InsertEdit;

/**
 * <h3>{@link OutlineNewOperation}</h3>
 */
public class OutlineNewOperation extends PrimaryTypeNewOperation {

  public static final String GET_CONFIGURED_OUTLINES = "getConfiguredOutlines";

  // in members
  private INlsEntry m_nlsEntry;
  private IType m_desktopType;

  public OutlineNewOperation(String outlineName, String packageName, IJavaProject javaProject) throws JavaModelException {
    super(outlineName, packageName, javaProject);

    // defaults
    setFlags(Flags.AccPublic);
    setSuperTypeSignature(RuntimeClasses.getSuperTypeSignature(IRuntimeClasses.IOutline, getJavaProject()));
    getCompilationUnitNewOp().setCommentSourceBuilder(CommentSourceBuilderFactory.createPreferencesCompilationUnitCommentBuilder());
    setTypeCommentSourceBuilder(CommentSourceBuilderFactory.createPreferencesTypeCommentBuilder());
    setPackageExportPolicy(ExportPolicy.ADD_PACKAGE);
    setFormatSource(true);
  }

  @Override
  public String getOperationName() {
    return "New Outline '" + getElementName() + "'...";
  }

  @Override
  public void run(IProgressMonitor monitor, IWorkingCopyManager workingCopyManager) throws CoreException {
    // nls method
    if (getNlsEntry() != null) {
      IMethodSourceBuilder nlsTextMethodBuilder = MethodSourceBuilderFactory.createOverrideMethodSourceBuilder(getSourceBuilder(), SdkProperties.METHOD_NAME_GET_CONFIGURED_TITLE);
      nlsTextMethodBuilder.setMethodBodySourceBuilder(MethodBodySourceBuilderFactory.createNlsEntryReferenceBody(getNlsEntry()));
      addSortedMethodSourceBuilder(SortedMemberKeyFactory.createMethodGetConfiguredKey(nlsTextMethodBuilder), nlsTextMethodBuilder);
    }

    super.run(monitor, workingCopyManager);

    // add to desktop
    if (TypeUtility.exists(getDesktopType())) {
      addOutlineToDesktop(getCreatedType(), monitor, workingCopyManager);
      addOutlineButtonToDesktop(getCreatedType(), monitor, workingCopyManager);
      // format desktop type
      JavaElementFormatOperation desktopFormatOp = new JavaElementFormatOperation(getDesktopType(), true);
      desktopFormatOp.validate();
      desktopFormatOp.run(monitor, workingCopyManager);
    }
  }

  private void addOutlineToDesktop(final IType outlineType, IProgressMonitor monitor, IWorkingCopyManager workingCopyManager) throws CoreException {
    IMethod method = TypeUtility.getMethod(getDesktopType(), GET_CONFIGURED_OUTLINES);
    if (TypeUtility.exists(method)) {
      MethodUpdateContentOperation updateContentOp = new MethodUpdateContentOperation(method) {
        @Override
        protected void updateMethodBody(Document methodBody, IImportValidator validator) throws CoreException {
          // try 'list.add(MyOutline.class)' pattern
          Matcher matcher = Pattern.compile("([a-zA-Z0-9\\_\\-]*)\\.add\\(\\s*[a-zA-Z0-9\\_\\-]*\\.class\\s*\\)\\;", Pattern.MULTILINE).matcher(methodBody.get());
          int index = -1;
          String listName = null;
          while (matcher.find()) {
            index = matcher.end();
            listName = matcher.group(1);
          }
          if (index > 0) {
            String addSource = listName + ".add(" + validator.getTypeName(SignatureCache.createTypeSignature(outlineType.getFullyQualifiedName())) + ".class);";
            if (methodBody.get().contains(addSource)) {
              return;
            }
            InsertEdit edit = new InsertEdit(index, "\n" + addSource);
            try {
              edit.apply(methodBody);
            }
            catch (Exception e) {
              ScoutSdk.logError("could not update method '" + getMethod().getElementName() + "' in type '" + getMethod().getDeclaringType().getFullyQualifiedName() + "'.", e);
            }
          }
        }
      };
      updateContentOp.setFormatSource(true);
      updateContentOp.validate();
      updateContentOp.run(monitor, workingCopyManager);
    }
    else {
      IMethodSourceBuilder overrideBuilder = MethodSourceBuilderFactory.createOverrideMethodSourceBuilder(GET_CONFIGURED_OUTLINES, getDesktopType());
      overrideBuilder.setMethodBodySourceBuilder(new IMethodBodySourceBuilder() {
        @Override
        public void createSource(IMethodSourceBuilder methodBuilder, StringBuilder source, String lineDelimiter, IJavaProject ownerProject, IImportValidator validator) throws CoreException {
          source.append(getOutlinesMethodBody(CollectionUtility.arrayList(outlineType), validator, lineDelimiter));
        }
      });
      MethodNewOperation overrideOp = new MethodNewOperation(overrideBuilder, getDesktopType());
      overrideOp.setFormatSource(true);
      IStructuredType structuredType = ScoutTypeUtility.createStructuredType(getDesktopType());
      overrideOp.setSibling(structuredType.getSiblingMethodConfigGetConfigured(GET_CONFIGURED_OUTLINES));
      overrideOp.validate();
      overrideOp.run(monitor, workingCopyManager);

    }
  }

  public static String getOutlinesMethodBody(List<IType> outlineTypes, IImportValidator validator, String lineDelimiter) {
    StringBuilder source = new StringBuilder();
    String listRef = validator.getTypeName(SignatureCache.createTypeSignature(List.class.getName()));
    String arrayListRef = validator.getTypeName(SignatureCache.createTypeSignature(ArrayList.class.getName()));
    String classRef = validator.getTypeName(SignatureCache.createTypeSignature(Class.class.getName()));
    String iOutlineRef = validator.getTypeName(SignatureCache.createTypeSignature(IRuntimeClasses.IOutline));

    StringBuilder genericPart = new StringBuilder().append(Signature.C_GENERIC_START).append(classRef).append(Signature.C_GENERIC_START).append("? extends ").append(iOutlineRef).append(Signature.C_GENERIC_END).append(Signature.C_GENERIC_END);

    source.append(listRef).append(genericPart).append(" outlines = ").append("new ").append(arrayListRef).append(genericPart).append("();").append(lineDelimiter);
    if (outlineTypes != null && outlineTypes.size() > 0) {
      for (IType t : outlineTypes) {
        if (TypeUtility.exists(t)) {
          String outlineRef = validator.getTypeName(SignatureCache.createTypeSignature(t.getFullyQualifiedName()));
          source.append("outlines.add(").append(outlineRef).append(".class);").append(lineDelimiter);
        }
      }
    }
    source.append("return outlines;");
    return source.toString();
  }

  private void addOutlineButtonToDesktop(IType outlineType, IProgressMonitor monitor, IWorkingCopyManager workingCopyManager) throws CoreException {

    final String className = getElementName() + SdkProperties.SUFFIX_VIEW_BUTTON;
    for (IType innerType : getDesktopType().getTypes()) {
      if (className.equals(innerType.getElementName())) {
        return;
      }
    }

    workingCopyManager.reconcile(getDesktopType().getCompilationUnit(), monitor);
    ITypeHierarchy desktopSuperHierarchy = TypeUtility.getSupertypeHierarchy(getDesktopType());
    final boolean isExtension = desktopSuperHierarchy.contains(TypeUtility.getType(IRuntimeClasses.IDesktopExtension));

    OrderedInnerTypeNewOperation outlineButtonOp = new OrderedInnerTypeNewOperation(className, getDesktopType());
    outlineButtonOp.setOrderDefinitionType(TypeUtility.getType(IRuntimeClasses.IViewButton));
    outlineButtonOp.setSuperTypeSignature(RuntimeClasses.getSuperTypeSignature(IRuntimeClasses.AbstractOutlineViewButton, getDesktopType().getJavaProject()));
    outlineButtonOp.setFlags(Flags.AccPublic);

    // constructor
    IMethodSourceBuilder constructorBuilder = MethodSourceBuilderFactory.createConstructorSourceBuilder(className);
    constructorBuilder.setCommentSourceBuilder(CommentSourceBuilderFactory.createPreferencesMethodCommentBuilder());
    constructorBuilder.setMethodBodySourceBuilder(new IMethodBodySourceBuilder() {
      @Override
      public void createSource(IMethodSourceBuilder methodBuilder, StringBuilder source, String lineDelimiter, IJavaProject ownerProject, IImportValidator validator) throws CoreException {
        source.append("super(");
        if (isExtension) {
          source.append("getCoreDesktop()");
        }
        else {
          source.append("Desktop.this");
        }
        source.append(",").append(validator.getTypeName(SignatureCache.createTypeSignature(OutlineNewOperation.this.getElementName()))).append(".class);");
      }
    });
    outlineButtonOp.addSortedMethodSourceBuilder(SortedMemberKeyFactory.createMethodConstructorKey(constructorBuilder), constructorBuilder);
    outlineButtonOp.validate();
    outlineButtonOp.run(monitor, workingCopyManager);
  }

  public INlsEntry getNlsEntry() {
    return m_nlsEntry;
  }

  public void setNlsEntry(INlsEntry nlsEntry) {
    m_nlsEntry = nlsEntry;
  }

  public void setDesktopType(IType desktopType) {
    m_desktopType = desktopType;
  }

  public IType getDesktopType() {
    return m_desktopType;
  }

}
