/*
 * Copyright 2000-2013 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.testIntegration;

import com.intellij.codeInsight.CodeInsightActionHandler;
import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.codeInsight.generation.GenerateMembersUtil;
import com.intellij.codeInsight.generation.OverrideImplementUtil;
import com.intellij.codeInsight.generation.PsiGenerationInfo;
import com.intellij.codeInsight.generation.actions.BaseGenerateAction;
import com.intellij.codeInsight.hint.HintManager;
import com.intellij.ide.fileTemplates.FileTemplateDescriptor;
import com.intellij.ide.fileTemplates.impl.AllFileTemplatesConfigurable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.PopupChooserBuilder;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.util.CommonRefactoringUtil;
import com.intellij.ui.components.JBList;
import com.intellij.util.Consumer;
import com.intellij.util.Function;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

public class BaseGenerateTestSupportMethodAction extends BaseGenerateAction {
  protected static final Logger LOG = Logger.getInstance("#" + BaseGenerateTestSupportMethodAction.class.getName());

  public BaseGenerateTestSupportMethodAction(TestIntegrationUtils.MethodKind methodKind) {
    super(new MyHandler(methodKind));
  }

  @Nullable
  @Override
  public AnAction createEditTemplateAction(DataContext dataContext) {
    final Project project = CommonDataKeys.PROJECT.getData(dataContext);
    final Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
    final PsiFile file = CommonDataKeys.PSI_FILE.getData(dataContext);
    final PsiClass targetClass = editor == null || file == null ? null : getTargetClass(editor, file);
    if (targetClass != null) {
      final List<TestFramework> frameworks = TestIntegrationUtils.findSuitableFrameworks(targetClass);
      final TestIntegrationUtils.MethodKind methodKind = ((MyHandler)getHandler()).myMethodKind;
      if (!frameworks.isEmpty()) {
        return new AnAction("Edit Template") {
          @Override
          public void actionPerformed(AnActionEvent e) {
            chooseAndPerform(editor, frameworks, new Consumer<TestFramework>() {
              @Override
              public void consume(TestFramework framework) {
                final FileTemplateDescriptor descriptor = methodKind.getFileTemplateDescriptor(framework);
                if (descriptor != null) {
                  final String fileName = descriptor.getFileName();
                  AllFileTemplatesConfigurable.editCodeTemplate(FileUtil.getNameWithoutExtension(fileName), project);
                } else {
                  HintManager.getInstance().showErrorHint(editor, "No template found for " + framework.getName() + ":" + BaseGenerateTestSupportMethodAction.this.getTemplatePresentation().getText());
                }
              }
            });
          }
        };
      }
    }
    return null;
  }

  @Override
  protected PsiClass getTargetClass(Editor editor, PsiFile file) {
    return findTargetClass(editor, file);
  }

  @Nullable
  private static PsiClass findTargetClass(@NotNull Editor editor, @NotNull PsiFile file) {
    int offset = editor.getCaretModel().getOffset();
    PsiElement element = file.findElementAt(offset);
    return element == null ? null : TestIntegrationUtils.findOuterClass(element);
  }

  @Override
  protected boolean isValidForClass(PsiClass targetClass) {
    List<TestFramework> frameworks = TestIntegrationUtils.findSuitableFrameworks(targetClass);
    if (frameworks.isEmpty()) return false;

    for (TestFramework each : frameworks) {
      if (isValidFor(targetClass, each)) return true;
    }
    return false;
  }

  @Override
  protected boolean isValidForFile(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) {
    if (file instanceof PsiCompiledElement) return false;

    PsiDocumentManager.getInstance(project).commitAllDocuments();

    PsiClass targetClass = getTargetClass(editor, file);
    return targetClass != null && isValidForClass(targetClass);
  }


  protected boolean isValidFor(PsiClass targetClass, TestFramework framework) {
    return true;
  }

  private static void chooseAndPerform(Editor editor, List<TestFramework> frameworks, final Consumer<TestFramework> consumer) {
    if (frameworks.size() == 1) {
      consumer.consume(frameworks.get(0));
      return;
    }

    final JList list = new JBList(frameworks.toArray(new TestFramework[frameworks.size()]));
    list.setCellRenderer(new DefaultListCellRenderer() {
      @Override
      public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
        Component result = super.getListCellRendererComponent(list, "", index, isSelected, cellHasFocus);
        if (value == null) return result;
        TestFramework framework = (TestFramework)value;

        setIcon(framework.getIcon());
        setText(framework.getName());

        return result;
      }
    });


    PopupChooserBuilder builder = new PopupChooserBuilder(list);
    builder.setFilteringEnabled(new Function<Object, String>() {
      @Override
      public String fun(Object o) {
        return ((TestFramework)o).getName();
      }
    });

    builder
      .setTitle("Choose Framework")
      .setItemChoosenCallback(new Runnable() {
        @Override
        public void run() {
          consumer.consume((TestFramework)list.getSelectedValue());
        }
      })
      .setMovable(true)
      .createPopup().showInBestPositionFor(editor);
  }

  private static class MyHandler implements CodeInsightActionHandler {
    private TestIntegrationUtils.MethodKind myMethodKind;

    private MyHandler(TestIntegrationUtils.MethodKind methodKind) {
      myMethodKind = methodKind;
    }

    public void invoke(@NotNull Project project, @NotNull final Editor editor, @NotNull final PsiFile file) {
      final PsiClass targetClass = findTargetClass(editor, file);
      final List<TestFramework> frameworks = new ArrayList<TestFramework>(TestIntegrationUtils.findSuitableFrameworks(targetClass));
      for (Iterator<TestFramework> iterator = frameworks.iterator(); iterator.hasNext(); ) {
        if (myMethodKind.getFileTemplateDescriptor(iterator.next()) == null) {
          iterator.remove();
        }
      }
      if (frameworks.isEmpty()) return;
      final Consumer<TestFramework> consumer = new Consumer<TestFramework>() {
        @Override
        public void consume(TestFramework framework) {
          if (framework == null) return;
          doGenerate(editor, file, targetClass, framework);
        }
      };

      chooseAndPerform(editor, frameworks, consumer);
    }


    private void doGenerate(final Editor editor, final PsiFile file, final PsiClass targetClass, final TestFramework framework) {
      if (!CommonRefactoringUtil.checkReadOnlyStatus(file)) return;

      ApplicationManager.getApplication().runWriteAction(new Runnable() {
        @Override
        public void run() {
          try {
            PsiDocumentManager.getInstance(file.getProject()).commitAllDocuments();
            PsiMethod method = generateDummyMethod(editor, file);
            if (method == null) return;

            TestIntegrationUtils.runTestMethodTemplate(myMethodKind, framework, editor, targetClass, method, "name", false, null);
          }
          catch (IncorrectOperationException e) {
            HintManager.getInstance().showErrorHint(editor, "Cannot generate method: " + e.getMessage());
            LOG.warn(e);
          }
        }
      });
    }

    @Nullable
    private static PsiMethod generateDummyMethod(Editor editor, PsiFile file) throws IncorrectOperationException {
      final PsiMethod method = TestIntegrationUtils.createDummyMethod(file);
      final PsiGenerationInfo<PsiMethod> info = OverrideImplementUtil.createGenerationInfo(method);

      int offset = findOffsetToInsertMethodTo(editor, file);
      GenerateMembersUtil.insertMembersAtOffset(file, offset, Collections.singletonList(info));

      final PsiMethod member = info.getPsiMember();
      return member != null ? CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(member) : null;
    }

    private static int findOffsetToInsertMethodTo(Editor editor, PsiFile file) {
      int result = editor.getCaretModel().getOffset();

      PsiClass classAtCursor = PsiTreeUtil.getParentOfType(file.findElementAt(result), PsiClass.class, false);

      while (classAtCursor != null && !(classAtCursor.getParent() instanceof PsiFile)) {
        result = classAtCursor.getTextRange().getEndOffset();
        classAtCursor = PsiTreeUtil.getParentOfType(classAtCursor, PsiClass.class);
      }

      return result;
    }

    public boolean startInWriteAction() {
      return false;
    }
  }
}
