/*
 * Copyright 2000-2009 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.intellij.execution.junit;

import com.intellij.execution.JavaExecutionUtil;
import com.intellij.execution.SingleClassConfiguration;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.listeners.RefactoringElementAdapter;
import com.intellij.refactoring.listeners.RefactoringElementListener;
import com.intellij.refactoring.listeners.UndoRefactoringElementListener;
import org.jetbrains.annotations.NotNull;

public class RefactoringListeners {
  public static RefactoringElementListener getListener(final PsiPackage psiPackage, final Accessor<PsiPackage> accessor) {
    final StringBuilder path = new StringBuilder();
    for (PsiPackage parent = accessor.getPsiElement(); parent != null; parent = parent.getParentPackage()) {
      if (parent.equals(psiPackage)) return new RefactorPackage(accessor, path.toString());
      if (path.length() > 0) path.insert(0, '.');
      path.insert(0, parent.getName());
    }
    return null;
  }

  public static RefactoringElementListener getListeners(final PsiClass psiClass, final Accessor<PsiClass> accessor) {
    final PsiClass aClass = accessor.getPsiElement();
    if (aClass == null) return null;
    final StringBuilder path = new StringBuilder();
    for (PsiClass parent = aClass; parent != null; parent = PsiTreeUtil.getParentOfType(parent, PsiClass.class, true)) {
      if (parent.equals(psiClass)) return new RefactorClass(accessor, path.toString());
      if (path.length() > 0) path.insert(0, '$');
      path.insert(0, parent.getName());
    }
    return null;
  }

  public static RefactoringElementListener getClassOrPackageListener(final PsiElement element, final Accessor<PsiClass> accessor) {
    if (element instanceof PsiClass) return getListeners((PsiClass)element, accessor);
    if (element instanceof PsiPackage) {
      final PsiClass aClass = accessor.getPsiElement();
      if (aClass == null) return null;
      return getListener((PsiPackage)element, new ClassPackageAccessor(accessor));
    }
    return null;

  }

  public interface Accessor<T extends PsiElement> {
    void setName(String qualifiedName);
    T getPsiElement();
    void setPsiElement(T psiElement);
  }

  public static class SingleClassConfigurationAccessor implements Accessor<PsiClass> {
    private final SingleClassConfiguration myConfiguration;

    public SingleClassConfigurationAccessor(final SingleClassConfiguration configuration) {
      myConfiguration = configuration;
    }

    public PsiClass getPsiElement() {
      return myConfiguration.getMainClass();
    }

    public void setPsiElement(final PsiClass psiClass) {
      myConfiguration.setMainClass(psiClass);
    }

    public void setName(final String qualifiedName) {
      myConfiguration.setMainClassName(qualifiedName);
    }
  }

  private static abstract class RenameElement<T extends PsiElement> extends RefactoringElementAdapter
                                                                    implements UndoRefactoringElementListener{
    private final Accessor<T> myAccessor;
    private final String myPath;

    public RenameElement(final Accessor<T> accessor, final String path) {
      myAccessor = accessor;
      myPath = path;
    }

    public void elementRenamedOrMoved(@NotNull final PsiElement newElement) {
      T newElement1 = (T)newElement;
      String qualifiedName = getQualifiedName(newElement1);
      if (myPath.length() > 0) {
        qualifiedName = qualifiedName + "." + myPath;
        newElement1 = findNewElement(newElement1, qualifiedName);
      }
      if (newElement1 != null) {
        myAccessor.setPsiElement(newElement1);
      }
      else {
        myAccessor.setName(qualifiedName);
      }
    }

    protected abstract T findNewElement(T newParent, String qualifiedName);

    protected abstract String getQualifiedName(T element);

    @Override
    public void undoElementMovedOrRenamed(@NotNull PsiElement newElement, @NotNull String oldQualifiedName) {
      myAccessor.setName(oldQualifiedName);
    }
  }

  private static class RefactorPackage extends RenameElement<PsiPackage> {
    public RefactorPackage(final Accessor<PsiPackage> accessor, final String path) {
      super(accessor, path);
    }

    public PsiPackage findNewElement(final PsiPackage psiPackage, final String qualifiedName) {
      return JavaPsiFacade.getInstance(psiPackage.getProject()).findPackage(qualifiedName);
    }

    public String getQualifiedName(final PsiPackage psiPackage) {
      return psiPackage.getQualifiedName();
    }
  }

  private static class RefactorClass extends RenameElement<PsiClass> {
    public RefactorClass(final Accessor<PsiClass> accessor, final String path) {
      super(accessor, path);
    }

    public PsiClass findNewElement(final PsiClass psiClass, final String qualifiedName) {
      return JavaPsiFacade.getInstance(psiClass.getProject())
        .findClass(qualifiedName.replace('$', '.'), GlobalSearchScope.moduleScope(JavaExecutionUtil.findModule(psiClass)));
    }

    public String getQualifiedName(final PsiClass psiClass) {
      return psiClass.getQualifiedName();
    }
  }

  private static class ClassPackageAccessor implements RefactoringListeners.Accessor<PsiPackage> {
    private final PsiPackage myContainingPackage;
    private final Module myModule;
    private final RefactoringListeners.Accessor<PsiClass> myAccessor;
    private final String myInpackageName;

    public ClassPackageAccessor(final RefactoringListeners.Accessor<PsiClass> accessor) {
      myAccessor = accessor;
      PsiClass aClass = myAccessor.getPsiElement();
      aClass = (PsiClass)aClass.getOriginalElement();
      myContainingPackage = JavaDirectoryService.getInstance().getPackage(aClass.getContainingFile().getContainingDirectory());
      myModule = JavaExecutionUtil.findModule(aClass);
      final String classQName = aClass.getQualifiedName();
      final String classPackageQName = myContainingPackage.getQualifiedName();
      if (classQName.startsWith(classPackageQName)) {
        final String inpackageName = classQName.substring(classPackageQName.length());
        if (StringUtil.startsWithChar(inpackageName, '.')) {
          myInpackageName = inpackageName.substring(1);
        }
        else {
          myInpackageName = inpackageName;
        }
      }
      else {
        myInpackageName = null;
      }
    }

    public PsiPackage getPsiElement() {
      return myContainingPackage;
    }

    public void setPsiElement(final PsiPackage psiPackage) {
      if (myInpackageName == null) return; //we can do nothing
      final String classQName = getClassQName(psiPackage.getQualifiedName());
      final PsiClass newClass = JUnitUtil.findPsiClass(classQName, myModule, psiPackage.getProject());
      if (newClass != null) {
        myAccessor.setPsiElement(newClass);
      }
      else {
        myAccessor.setName(classQName);
      }
    }

    public void setName(final String qualifiedName) {
      myAccessor.setName(getClassQName(qualifiedName));
    }

    private String getClassQName(final String packageQName) {
      if (packageQName.length() > 0) {
        return packageQName + '.' + myInpackageName;
      }
      else {
        return myInpackageName;
      }
    }
  }
}
