/*
 * 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.ide.hierarchy.method;

import com.intellij.codeInsight.generation.OverrideImplementUtil;
import com.intellij.ide.hierarchy.HierarchyNodeDescriptor;
import com.intellij.ide.hierarchy.MethodHierarchyBrowserBase;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.ReadonlyStatusHandler;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.psi.*;
import com.intellij.psi.util.MethodSignature;
import com.intellij.util.IncorrectOperationException;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

abstract class OverrideImplementMethodAction extends AnAction {
  private static final Logger LOG = Logger.getInstance("#com.intellij.ide.hierarchy.method.OverrideImplementMethodAction");

  public final void actionPerformed(final AnActionEvent event) {
    final DataContext dataContext = event.getDataContext();
    final MethodHierarchyBrowser methodHierarchyBrowser = (MethodHierarchyBrowser)MethodHierarchyBrowserBase.DATA_KEY.getData(dataContext);
    if (methodHierarchyBrowser == null) return;
    final Project project = CommonDataKeys.PROJECT.getData(dataContext);
    if (project == null) return;

    final String commandName = event.getPresentation().getText();
    ApplicationManager.getApplication().runWriteAction(new Runnable() {
      public void run() {
        CommandProcessor.getInstance().executeCommand(project, new Runnable() {
          public void run() {

            try{
              final HierarchyNodeDescriptor[] selectedDescriptors = methodHierarchyBrowser.getSelectedDescriptors();
              if (selectedDescriptors.length > 0) {
                final List<VirtualFile> files = new ArrayList<VirtualFile>(selectedDescriptors.length);
                for (HierarchyNodeDescriptor selectedDescriptor : selectedDescriptors) {
                  final PsiFile containingFile = ((MethodHierarchyNodeDescriptor)selectedDescriptor).getPsiClass().getContainingFile();
                  if (containingFile != null) {
                    final VirtualFile vFile = containingFile.getVirtualFile();
                    if (vFile != null) {
                      files.add(vFile);
                    }
                  }
                }
                final ReadonlyStatusHandler.OperationStatus status = ReadonlyStatusHandler.getInstance(project).ensureFilesWritable(VfsUtil.toVirtualFileArray(files));
                if (!status.hasReadonlyFiles()) {
                  for (HierarchyNodeDescriptor selectedDescriptor : selectedDescriptors) {
                    OverrideImplementUtil.overrideOrImplement(((MethodHierarchyNodeDescriptor)selectedDescriptor).getPsiClass(), methodHierarchyBrowser.getBaseMethod());
                  }
                  ToolWindowManager.getInstance(project).activateEditorComponent();
                }
                else {
                  ApplicationManager.getApplication().invokeLater(new Runnable() {
                    public void run() {
                      Messages.showErrorDialog(project, status.getReadonlyFilesMessage(), commandName);
                    }
                  });
                }
              }
            }
            catch(IncorrectOperationException e){
              LOG.error(e);
            }
          }
        }, commandName, null);
      }
    });
  }

  public final void update(final AnActionEvent e) {
    final Presentation presentation = e.getPresentation();
    final DataContext dataContext = e.getDataContext();

    final MethodHierarchyBrowser methodHierarchyBrowser = (MethodHierarchyBrowser)MethodHierarchyBrowserBase.DATA_KEY.getData(dataContext);
    if (methodHierarchyBrowser == null) {
      presentation.setEnabled(false);
      presentation.setVisible(false);
      return;
    }
    final Project project = CommonDataKeys.PROJECT.getData(dataContext);
    if (project == null) {
      presentation.setEnabled(false);
      presentation.setVisible(false);
      return;
    }

    final HierarchyNodeDescriptor[] selectedDescriptors = methodHierarchyBrowser.getSelectedDescriptors();
    int toImplement = 0;
    int toOverride = 0;

    for (final HierarchyNodeDescriptor descriptor : selectedDescriptors) {
      if (canImplementOverride((MethodHierarchyNodeDescriptor)descriptor, methodHierarchyBrowser, true)) {
        if (toOverride > 0) {
          // no mixed actions allowed
          presentation.setEnabled(false);
          presentation.setVisible(false);
          return;
        }
        toImplement++;
      }
      else if (canImplementOverride((MethodHierarchyNodeDescriptor)descriptor, methodHierarchyBrowser, false)) {
        if (toImplement > 0) {
          // no mixed actions allowed
          presentation.setEnabled(false);
          presentation.setVisible(false);
          return;
        }
        toOverride++;
      }
      else {
        // no action is applicable to this node
        presentation.setEnabled(false);
        presentation.setVisible(false);
        return;
      }
    }

    presentation.setVisible(true);

    update(presentation, toImplement, toOverride);
  }

  protected abstract void update(Presentation presentation, int toImplement, int toOverride);

  private static boolean canImplementOverride(final MethodHierarchyNodeDescriptor descriptor, final MethodHierarchyBrowser methodHierarchyBrowser, final boolean toImplement) {
    final PsiClass psiClass = descriptor.getPsiClass();
    if (psiClass == null || psiClass instanceof PsiSyntheticClass) return false;
    final PsiMethod baseMethod = methodHierarchyBrowser.getBaseMethod();
    if (baseMethod == null) return false;
    final MethodSignature signature = baseMethod.getSignature(PsiSubstitutor.EMPTY);

    Collection<MethodSignature> allOriginalSignatures = toImplement
                                                        ? OverrideImplementUtil.getMethodSignaturesToImplement(psiClass)
                                                        : OverrideImplementUtil.getMethodSignaturesToOverride(psiClass);
    for (final MethodSignature originalSignature : allOriginalSignatures) {
      if (originalSignature.equals(signature)) {
        return true;
      }
    }

    return false;
  }
}
