package com.cedricziel.idea.typo3.persistence.codeInsight;

import com.cedricziel.idea.typo3.psi.PhpElementsUtil;
import com.intellij.codeInsight.completion.*;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.openapi.fileEditor.impl.LoadTextUtil;
import com.intellij.patterns.PlatformPatterns;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.search.FilenameIndex;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ProcessingContext;
import com.jetbrains.php.PhpIndex;
import com.jetbrains.php.lang.psi.elements.*;
import org.jetbrains.annotations.NotNull;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Matches
 * <p>
 * \TYPO3\CMS\Core\Database::getConnectionForTable()
 * \TYPO3\CMS\Core\Database::getQueryBuilderForTable()
 * <p>
 * and provides autocompletion
 */
public class DoctrineTablesContributor extends CompletionContributor {

    private static final String EXT_TABLES_SQL_FILENAME = "ext_tables.sql";

    public DoctrineTablesContributor() {
        extend(CompletionType.BASIC, PlatformPatterns.psiElement(), new CompletionProvider<CompletionParameters>() {
            @Override
            protected void addCompletions(@NotNull CompletionParameters completionParameters, ProcessingContext processingContext, @NotNull CompletionResultSet completionResultSet) {
                PsiElement element = completionParameters.getPosition().getParent();
                ParameterList parameterList = PsiTreeUtil.getParentOfType(element, ParameterList.class);
                if (parameterList == null) {
                    return;
                }

                MethodReference methodReference = PsiTreeUtil.getParentOfType(element, MethodReference.class);
                if (methodReference == null) {
                    return;
                }

                if (PhpElementsUtil.isMethodWithFirstStringOrFieldReference(methodReference, "getConnectionForTable")) {
                    completeAvailableTables(methodReference, completionResultSet);

                    return;
                }

                if (PhpElementsUtil.isMethodWithFirstStringOrFieldReference(methodReference, "getQueryBuilderForTable")) {
                    completeAvailableTables(methodReference, completionResultSet);

                    return;
                }

                String methodName = methodReference.getName();
                ClassReference classReference = PsiTreeUtil.getChildOfType(methodReference, ClassReference.class);
                if (classReference != null && methodName != null) {
                    String name = classReference.getFQN();

                    // there can be multiple classes in one project scope that share the same FQN
                    Collection<PhpClass> phpClasses = PhpIndex.getInstance(element.getProject()).getClassesByFQN(name);
                    for (PhpClass c : phpClasses) {
                        Method method = c.findMethodByName(methodName);

                        ParameterList originalMethodParameterList = PsiTreeUtil.getChildOfType(method, ParameterList.class);
                        if (originalMethodParameterList != null) {
                            Parameter firstParameter = PsiTreeUtil.getChildOfType(originalMethodParameterList, Parameter.class);

                            // completion on method with no arguments
                            if (firstParameter == null) {
                                return;
                            }

                            String parameterName = firstParameter.getName();
                            if (parameterName.equals("table") || parameterName.equals("tableName")) {
                                completeAvailableTables(methodReference, completionResultSet);

                                return;
                            }
                        }
                    }
                }
            }
        });
    }

    private void completeAvailableTables(MethodReference element, @NotNull CompletionResultSet completionResultSet) {
        PsiFile[] extSqlFiles = FilenameIndex.getFilesByName(element.getProject(), EXT_TABLES_SQL_FILENAME, GlobalSearchScope.allScope(element.getProject()));

        Set<String> tableNames = new HashSet<>();

        for (PsiFile psiFile : extSqlFiles) {

            if (psiFile != null) {

                CharSequence charSequence = LoadTextUtil.loadText(psiFile.getVirtualFile());

                final Matcher matcher = Pattern
                        .compile("create\\s+table\\s+(if\\s+not\\s+exists\\s+)?([a-zA-Z_0-9]+)", Pattern.CASE_INSENSITIVE)
                        .matcher(charSequence);

                try {
                    while (matcher.find()) {
                        if (matcher.groupCount() < 2) {
                            return;
                        }

                        tableNames.add(matcher.group(2));
                    }
                } catch (IllegalStateException e) {
                    // no matches
                }
            }
        }

        for (String name : tableNames) {
            completionResultSet.addElement(new LookupElement() {
                @NotNull
                @Override
                public String getLookupString() {

                    return name;
                }
            });
        }
    }
}

@@ -122,41 +122,44 @@
 com.
-intellij.codeInsight.comp
+cedricziel.idea.typo3.util.Tab
 le
+U
 ti
-on.*
+l
 ;%0Aim
@@ -192,86 +192,20 @@
 ght.
-lookup.LookupElement;%0Aimport com.intellij.openapi.fileEditor.impl.LoadTextUtil
+completion.*
 ;%0Aim
@@ -289,137 +289,8 @@
 nt;%0A
-import com.intellij.psi.PsiFile;%0Aimport com.intellij.psi.search.FilenameIndex;%0Aimport com.intellij.psi.search.GlobalSearchScope;%0A
 impo
@@ -527,120 +527,8 @@
 ion;
-%0Aimport java.util.HashSet;%0Aimport java.util.Set;%0Aimport java.util.regex.Matcher;%0Aimport java.util.regex.Pattern;
 %0A%0A/*
@@ -773,85 +773,8 @@
  %7B%0A%0A
-    private static final String EXT_TABLES_SQL_FILENAME = %22ext_tables.sql%22;%0A%0A
     
@@ -1752,32 +1752,42 @@
                 
+TableUtil.
 completeAvailabl
@@ -1784,32 +1784,36 @@
 teAvailableTable
+Name
 s(methodReferenc
@@ -1805,32 +1805,45 @@
 (methodReference
+.getProject()
 , completionResu
@@ -2033,32 +2033,42 @@
                 
+TableUtil.
 completeAvailabl
@@ -2065,32 +2065,36 @@
 teAvailableTable
+Name
 s(methodReferenc
@@ -2086,32 +2086,45 @@
 (methodReference
+.getProject()
 , completionResu
@@ -3556,24 +3556,34 @@
             
+TableUtil.
 completeAvai
@@ -3592,16 +3592,20 @@
 bleTable
+Name
 s(method
@@ -3613,16 +3613,29 @@
 eference
+.getProject()
 , comple
@@ -3822,1420 +3822,7 @@
    %7D
-%0A%0A    private void completeAvailableTables(MethodReference element, @NotNull CompletionResultSet completionResultSet) %7B%0A        PsiFile%5B%5D extSqlFiles = FilenameIndex.getFilesByName(element.getProject(), EXT_TABLES_SQL_FILENAME, GlobalSearchScope.allScope(element.getProject()));%0A%0A        Set%3CString%3E tableNames = new HashSet%3C%3E();%0A%0A        for (PsiFile psiFile : extSqlFiles) %7B%0A%0A            if (psiFile != null) %7B%0A%0A                CharSequence charSequence = LoadTextUtil.loadText(psiFile.getVirtualFile());%0A%0A                final Matcher matcher = Pattern%0A                        .compile(%22create%5C%5Cs+table%5C%5Cs+(if%5C%5Cs+not%5C%5Cs+exists%5C%5Cs+)?(%5Ba-zA-Z_0-9%5D+)%22, Pattern.CASE_INSENSITIVE)%0A                        .matcher(charSequence);%0A%0A                try %7B%0A                    while (matcher.find()) %7B%0A                        if (matcher.groupCount() %3C 2) %7B%0A                            return;%0A                        %7D%0A%0A                        tableNames.add(matcher.group(2));%0A                    %7D%0A                %7D catch (IllegalStateException e) %7B%0A                    // no matches%0A                %7D%0A            %7D%0A        %7D%0A%0A        for (String name : tableNames) %7B%0A            completionResultSet.addElement(new LookupElement() %7B%0A                @NotNull%0A                @Override%0A                public String getLookupString() %7B%0A%0A                    return name;%0A                %7D%0A            %7D);%0A        %7D%0A    %7D
 %0A%7D%0A

Use TableUtil in DoctrineTablesContributor