/*
 * Copyright 2000-2012 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.
 */

/*
 * User: anna
 * Date: 18-Jun-2007
 */
package com.theoryinpractice.testng.inspection;

import com.intellij.codeInspection.*;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileChooser.FileChooser;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.search.PsiNonJavaFileReferenceProcessor;
import com.intellij.psi.search.PsiSearchHelper;
import com.intellij.psi.util.PsiClassUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.IncorrectOperationException;
import com.theoryinpractice.testng.configuration.browser.SuiteBrowser;
import com.theoryinpractice.testng.util.TestNGUtil;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

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

public class UndeclaredTestInspection extends BaseJavaLocalInspectionTool {
  private static final Logger LOG = Logger.getInstance("#" + UndeclaredTestInspection.class.getName());

  @Nls
  @NotNull
  public String getGroupDisplayName() {
    return TestNGUtil.TESTNG_GROUP_NAME;
  }

  @Nls
  @NotNull
  public String getDisplayName() {
    return "Undeclared test";
  }

  @NonNls
  @NotNull
  public String getShortName() {
    return "UndeclaredTests";
  }

  @Nullable
  public ProblemDescriptor[] checkClass(@NotNull final PsiClass aClass,
                                        @NotNull final InspectionManager manager,
                                        final boolean isOnTheFly) {
    if (TestNGUtil.hasTest(aClass) && PsiClassUtil.isRunnableClass(aClass, true)) {
      final Project project = aClass.getProject();
      final String qName = aClass.getQualifiedName();
      if (qName == null) return null;
      final String packageQName = StringUtil.getPackageName(qName);
      final List<String> names = new ArrayList<String>();
      for(int i = 0; i < qName.length(); i++) {
        if (qName.charAt(i) == '.') {
          names.add(qName.substring(0, i));
        }
      }
      names.add(qName);
      Collections.reverse(names);

      for (final String name : names) {
        final boolean isFullName = qName.equals(name);
        final boolean[] found = new boolean[]{false};
        PsiSearchHelper.SERVICE.getInstance(project)
          .processUsagesInNonJavaFiles(name, new PsiNonJavaFileReferenceProcessor() {
            public boolean process(final PsiFile file, final int startOffset, final int endOffset) {
              if (file.findReferenceAt(startOffset) != null) {
                if (!isFullName) { //special package tag required
                  final XmlTag tag = PsiTreeUtil.getParentOfType(file.findElementAt(startOffset), XmlTag.class);
                  if (tag == null || !tag.getName().equals("package")) {
                    return true;
                  }
                  final XmlAttribute attribute = tag.getAttribute("name");
                  if (attribute == null) return true;
                  final String value = attribute.getValue();
                  if (value == null) return true;
                  if (!value.endsWith(".*") && !value.equals(packageQName)) return true;
                }
                found[0] = true;
                return false;
              }
              return true;
            }
          }, new TestNGSearchScope(project));
        if (found[0]) return null;
      }
      final PsiIdentifier nameIdentifier = aClass.getNameIdentifier();
      LOG.assertTrue(nameIdentifier != null);
      return new ProblemDescriptor[]{manager.createProblemDescriptor(nameIdentifier, "Undeclared test \'" + aClass.getName() + "\'",
                                                                     isOnTheFly, new LocalQuickFix[]{new RegisterClassFix(aClass),
                                                                       new CreateTestngFix()},
                                                                     ProblemHighlightType.GENERIC_ERROR_OR_WARNING)};
    }
    return null;
  }

  private static class RegisterClassFix implements LocalQuickFix {
    private final PsiClass myClass;

    public RegisterClassFix(final PsiClass aClass) {
      myClass = aClass;
    }

    @NotNull
    public String getName() {
      return "Register \'" + myClass.getName() + "\'";
    }

    @NotNull
    public String getFamilyName() {
      return getName();
    }

    public void applyFix(@NotNull final Project project, @NotNull ProblemDescriptor descriptor) {
      final PsiClass psiClass = PsiTreeUtil.getParentOfType(descriptor.getPsiElement(), PsiClass.class);
      LOG.assertTrue(psiClass != null);
      SwingUtilities.invokeLater(new Runnable() { //need to show dialog

        public void run() {
          final String testngXmlPath = new SuiteBrowser(project).showDialog();
          if (testngXmlPath == null) return;
          final VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByPath(testngXmlPath);
          LOG.assertTrue(virtualFile != null);
          final PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile);
          LOG.assertTrue(psiFile instanceof XmlFile);
          final XmlFile testngXML = (XmlFile)psiFile;
          new WriteCommandAction(project, getName(), testngXML) {
            protected void run(final Result result) throws Throwable {
              patchTestngXml(testngXML, psiClass);
            }
          }.execute();
        }
      });
    }
  }

  //make public for tests only
  public static void patchTestngXml(final XmlFile testngXML, final PsiClass psiClass) {
    final XmlTag rootTag = testngXML.getDocument().getRootTag();
    if (rootTag != null && rootTag.getName().equals("suite")) {
      try {
        XmlTag testTag = rootTag.findFirstSubTag("test");
        if (testTag == null) {
          testTag = (XmlTag)rootTag.add(rootTag.createChildTag("test", rootTag.getNamespace(), null, false));
          testTag.setAttribute("name", psiClass.getName());
        }
        XmlTag classesTag = testTag.findFirstSubTag("classes");
        if (classesTag == null) {
          classesTag = (XmlTag)testTag.add(testTag.createChildTag("classes", testTag.getNamespace(), null, false));
        }
        final XmlTag classTag = (XmlTag)classesTag.add(classesTag.createChildTag("class", classesTag.getNamespace(), null, false));
        final String qualifiedName = psiClass.getQualifiedName();
        LOG.assertTrue(qualifiedName != null);
        classTag.setAttribute("name", qualifiedName);
      }
      catch (IncorrectOperationException e) {
        LOG.error(e);
      }
    }
  }

  private static class CreateTestngFix implements LocalQuickFix {
    @NotNull
    public String getName() {
      return "Create suite";
    }

    @NotNull
    public String getFamilyName() {
      return getName();
    }

    public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) {
      final PsiClass psiClass = PsiTreeUtil.getParentOfType(descriptor.getPsiElement(), PsiClass.class);
      SwingUtilities.invokeLater(new Runnable() {
        public void run() {
          final VirtualFile file = FileChooser.chooseFile(FileChooserDescriptorFactory.createSingleFolderDescriptor(), project, null);
          if (file != null) {
            final PsiManager psiManager = PsiManager.getInstance(project);
            final PsiDirectory directory = psiManager.findDirectory(file);
            LOG.assertTrue(directory != null);
            new WriteCommandAction(project, getName(), null) {
              protected void run(final Result result) throws Throwable {
                XmlFile testngXml = (XmlFile)PsiFileFactory.getInstance(psiManager.getProject())
                  .createFileFromText("testng.xml", "<!DOCTYPE suite SYSTEM \"http://testng.org/testng-1.0.dtd\">\n<suite></suite>");
                try {
                  testngXml = (XmlFile)directory.add(testngXml);
                }
                catch (IncorrectOperationException e) {
                  //todo suggest new name
                  return;
                }
                patchTestngXml(testngXml, psiClass);
              }
            }.execute();
          }
        }
      });
    }
  }
}
