/*
 * 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.jetbrains.python;

import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.lexer.Lexer;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiLanguageInjectionHost;
import com.jetbrains.python.codeInsight.regexp.PythonRegexpParserDefinition;
import com.jetbrains.python.codeInsight.regexp.PythonVerboseRegexpLanguage;
import com.jetbrains.python.codeInsight.regexp.PythonVerboseRegexpParserDefinition;
import com.jetbrains.python.fixtures.PyLexerTestCase;
import com.jetbrains.python.fixtures.PyTestCase;
import org.jetbrains.annotations.NotNull;

import java.util.List;

/**
 * @author yole
 */
public class PyRegexpTest extends PyTestCase {
  public void testNestedCharacterClasses() {  // PY-2908
    doTestHighlighting();
  }

  public void testNestedCharacterClassesLexer() {
    doTestLexer("[][]", "CLASS_BEGIN", "CHARACTER", "CHARACTER", "CLASS_END");
  }

  public void testNestedCharacterClasses2() {  // PY-2908
    doTestHighlighting();
  }

  public void testOctal() {  // PY-2906
    doTestHighlighting();
  }

  public void testBraceInPythonCharacterClass() {  // PY-1929
    doTestHighlighting();
  }

  public void testNegatedBraceInCharacterClass() {
    doTestLexer("[^][]", "CLASS_BEGIN", "CARET", "CHARACTER", "CHARACTER", "CLASS_END");
  }

  public void testDanglingMetacharacters() {  // PY-2430
    doTestHighlighting();
  }

  public void testVerbose() {
    Lexer lexer = new PythonVerboseRegexpParserDefinition().createLexer(myFixture.getProject());
    PyLexerTestCase.doLexerTest("# abc", lexer, "COMMENT", "COMMENT");
  }

  public void testRedundantEscapeSingleQuote() {  // PY-5027
    doTestHighlighting();
  }

  public void testBraceCommaN() {  // PY-8304
    doTestHighlighting();
  }

  public void testVerboseAsKwArg() {  // PY-8143
    doTestHighlighting();
  }

  public void testVerboseEscapedHash() {  // PY-6545
    doTestHighlighting();
  }

  public void _testDoubleOpenCurly() {  // PY-8252
    doTestHighlighting();
  }

  public void testReSubNotRegexp() {  // PY-11069
    doTestHighlighting();
  }

  public void testSingleStringRegexpAutoInjection() {
    doTestInjectedText("import re\n" +
                        "\n" +
                        "re.search('<caret>.*bar',\n" +
                        "          'foobar')\n",
                       ".*bar");
  }

  // PY-11057
  public void testAdjacentStringRegexpAutoInjection() {
    doTestInjectedText("import re\n" +
                        "\n" +
                        "re.search('<caret>.*()'\n" +
                        "          'abc',\n" +
                        "          'foo')\n",
                       ".*()abc");
  }

  public void testParenthesizedStringRegexpAutoInjection() {
    doTestInjectedText("import re\n" +
                       "\n" +
                       "re.search((('<caret>foo')), 'foobar')\n",
                       "foo");
  }

  public void testConcatStringRegexpAutoInjection() {
    doTestInjectedText("import re\n" +
                       "\n" +
                       "re.search('<caret>(.*' + 'bar)' + 'baz', 'foobar')\n",
                       "(.*bar)baz");
  }

  public void testConcatStringWithValuesRegexpAutoInjection() {
    doTestInjectedText("import re\n" +
                       "\n" +
                       "def f(x, y):\n" +
                       "    re.search('<caret>.*(' + x + ')' + y, 'foo')\n",
                       ".*(missing_value)missing_value");
  }

  public void testPercentFormattingRegexpAutoInjection() {
    doTestInjectedText("import re \n" +
                       "\n" +
                       "def f(x, y):\n" +
                       "    re.search('<caret>.*%s-%d' % (x, y), 'foo')\n",
                       ".*missing_value-missing_value");
  }

  public void testNewStyleFormattingRegexpAutoInjection() {
    doTestInjectedText("import re\n" +
                       "\n" +
                       "def f(x, y):\n" +
                       "    re.search('<caret>.*{foo}-{}'.format(x, foo=y), 'foo')\n",
                       ".*missing_value-missing_value");
  }

  public void testNewStyleFormattingEndsWithConstant() {
    doTestInjectedText("import re\n" +
                       "\n" +
                       "def f(**kwargs):" +
                       "    re.search('<caret>(foo{bar}baz$)'.format(**kwargs), 'foo')\n",
                       "(foomissing_valuebaz$)");
  }

  // PY-18881
  public void testVerboseSyntaxWithShortFlag() {
    final PsiElement element =
      doTestInjectedText("import re\n" +
                         "\n" +
                         "re.search(\"\"\"\n" +
                         ".* # <caret>comment\n" +
                         "\"\"\", re.I | re.M | re.X)",
                         "\n.* # comment\n");
    assertEquals(element.getLanguage(), PythonVerboseRegexpLanguage.INSTANCE);
  }

  // PY-16404
  public void testFullmatch() {
    doTestInjectedText("import re\n" +
                       "re.fullmatch(\"<caret>\\w+\", \"string\"",
                       "\\w+");
  }

  @NotNull
  private PsiElement doTestInjectedText(@NotNull String text, @NotNull String expected) {
    myFixture.configureByText(PythonFileType.INSTANCE, text);
    final InjectedLanguageManager languageManager = InjectedLanguageManager.getInstance(myFixture.getProject());
    final PsiLanguageInjectionHost host = languageManager.getInjectionHost(getElementAtCaret());
    assertNotNull(host);
    final List<Pair<PsiElement, TextRange>> files = languageManager.getInjectedPsiFiles(host);
    assertNotNull(files);
    assertFalse(files.isEmpty());
    final PsiElement injected = files.get(0).getFirst();
    assertEquals(expected, injected.getText());
    return injected;
  }

  @NotNull
  private PsiElement getElementAtCaret() {
    final Editor editor = myFixture.getEditor();
    final Document document = editor.getDocument();
    final PsiFile file = PsiDocumentManager.getInstance(myFixture.getProject()).getPsiFile(document);
    assertNotNull(file);
    final PsiElement element = file.findElementAt(myFixture.getCaretOffset());
    assertNotNull(element);
    return element;
  }

  private void doTestHighlighting() {
    myFixture.testHighlighting(true, false, true, "regexp/" + getTestName(true) + ".py");
  }

  private void doTestLexer(final String text, String... expectedTokens) {
    Lexer lexer = new PythonRegexpParserDefinition().createLexer(myFixture.getProject());
    PyLexerTestCase.doLexerTest(text, lexer, expectedTokens);
  }
}

@@ -2788,17 +2788,16 @@
 ic void 
-_
 testDoub

enable test now that issue is fixed