// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.jetbrains

import com.intellij.codeInsight.completion.CompletionResultSet
import com.intellij.codeInsight.lookup.LookupElement
import com.intellij.codeInsight.lookup.LookupElementBuilder
import com.intellij.ide.util.TreeChooser
import com.intellij.ide.util.gotoByName.GotoSymbolModel2
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.ComponentWithBrowseButton
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiDirectory
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFileSystemItem
import com.intellij.psi.PsiNamedElement
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.util.QualifiedName
import com.intellij.ui.TextAccessor
import com.intellij.util.ProcessingContext
import com.intellij.util.TextFieldCompletionProvider
import com.intellij.util.textCompletion.TextFieldWithCompletion
import com.jetbrains.extensions.getQName
import com.jetbrains.extensions.python.toPsi
import com.jetbrains.extensions.ContextAnchor
import com.jetbrains.extensions.QNameResolveContext
import com.jetbrains.extensions.resolveToElement
import com.jetbrains.python.PyGotoSymbolContributor
import com.jetbrains.python.PyNames
import com.jetbrains.python.PyTreeChooserDialog
import com.jetbrains.python.psi.PyFile
import com.jetbrains.python.psi.PyQualifiedNameOwner
import com.jetbrains.python.psi.PyTypedElement
import com.jetbrains.python.psi.PyUtil
import com.jetbrains.python.psi.stubs.PyClassNameIndex
import com.jetbrains.python.psi.stubs.PyFunctionNameIndex
import com.jetbrains.python.psi.types.PyModuleType
import com.jetbrains.python.psi.types.PyType
import com.jetbrains.python.psi.types.TypeEvalContext


/**
 * Python module is file or package with init.py.
 * Only source based packages are supported.
 * [PySymbolFieldWithBrowseButton] use this function to get list of root names
 */
fun isPythonModule(element: PsiElement): Boolean = element is PyFile || (element as? PsiDirectory)?.let {
  it.findFile(PyNames.INIT_DOT_PY) != null
} ?: false

/**
 * Text field to enter python symbols and browse button (from [PyGotoSymbolContributor]).
 * Supports auto-completion for symbol fully qualified names inside of textbox
 * @param filter lambda to filter symbols
 * @param startFromDirectory symbols resolved against module, but may additionally be resolved against this folder if provided like in [QNameResolveContext.folderToStart]
 *
 */
class PySymbolFieldWithBrowseButton(contextAnchor: ContextAnchor,
                                    filter: ((PsiElement) -> Boolean)? = null,
                                    startFromDirectory: (() -> VirtualFile)? = null) : TextAccessor, ComponentWithBrowseButton<TextFieldWithCompletion>(
  TextFieldWithCompletion(contextAnchor.project, PyNameCompletionProvider(contextAnchor, filter, startFromDirectory), "", true, true, true),
  null) {
  init {
    addActionListener {
      val dialog = PySymbolChooserDialog(contextAnchor.project, contextAnchor.scope, filter)
      dialog.showDialog()
      val element = dialog.selected
      if (element is PyQualifiedNameOwner) {
        childComponent.setText(element.qualifiedName)
      }
      if (element is PyFile) {
        childComponent.setText(element.getQName()?.toString())
      }
    }
  }

  override fun setText(text: String?) {
    childComponent.setText(text)
  }

  override fun getText(): String = childComponent.text
}

private fun PyType.getVariants(element: PsiElement): Array<LookupElement> =
  this.getCompletionVariants("", element, ProcessingContext()).filterIsInstance(LookupElement::class.java).toTypedArray()

private class PyNameCompletionProvider(private val contextAnchor: ContextAnchor,
                                       private val filter: ((PsiElement) -> Boolean)?,
                                       private val startFromDirectory: (() -> VirtualFile)? = null) : TextFieldCompletionProvider() {
  override fun addCompletionVariants(text: String, offset: Int, prefix: String, result: CompletionResultSet) {

    val lookups: Array<LookupElement>
    var name: QualifiedName? = null
    if ('.' !in text) {
      lookups = contextAnchor.getRoots()
        .map { rootFolder -> rootFolder.children.map { it.toPsi(contextAnchor.project) } }
        .flatten()
        .filterNotNull()
        .filter { isPythonModule(it) }
        .map { LookupElementBuilder.create(it, it.virtualFile.nameWithoutExtension) }
        .distinctBy { it.lookupString }
        .toTypedArray()
    }
    else {

      val evalContext = TypeEvalContext.userInitiated(contextAnchor.project, null)
      name = QualifiedName.fromDottedString(text)
      val resolveContext = QNameResolveContext(contextAnchor, evalContext = evalContext, allowInaccurateResult = false,
                                               folderToStart = startFromDirectory?.invoke())
      var element = name.resolveToElement(resolveContext, stopOnFirstFail = true)

      if (element == null && name.componentCount > 1) {
        name = name.removeLastComponent()
        element = name.resolveToElement(resolveContext, stopOnFirstFail = true)
      }
      if (element == null) {
        return
      }

      lookups = when (element) {
        is PyFile -> PyModuleType(element).getVariants(element)
        is PsiDirectory -> {
          val init = PyUtil.turnDirIntoInit(element) as? PyFile ?: return
          PyModuleType(init).getVariants(element) +
          element.children.filterIsInstance(PsiFileSystemItem::class.java)
            // For package we need all symbols in initpy and all filesystem children of this folder except initpy itself
            .filterNot { it.name == PyNames.INIT_DOT_PY }
            .map { LookupElementBuilder.create(it, it.virtualFile.nameWithoutExtension) }
        }
        is PyTypedElement -> {
          evalContext.getType(element)?.getVariants(element) ?: return
        }
        else -> return
      }
    }
    result.addAllElements(lookups
                            .filter { it.psiElement != null }
                            .filter { filter?.invoke(it.psiElement!!) ?: true }
                            .map { if (name != null) LookupElementBuilder.create("$name.${it.lookupString}") else it })
  }
}

private class PySymbolChooserDialog(project: Project, scope: GlobalSearchScope, private val filter: ((PsiElement) -> Boolean)?)
  : PyTreeChooserDialog<PsiNamedElement>("Choose Symbol", PsiNamedElement::class.java,
                                         project,
                                         scope,
                                         TreeChooser.Filter { filter?.invoke(it) ?: true }, null) {
  override fun findElements(name: String, searchScope: GlobalSearchScope): Collection<PsiNamedElement> {
    return PyClassNameIndex.find(name, project, searchScope) + PyFunctionNameIndex.find(name, project, searchScope)
  }

  override fun createChooseByNameModel() = GotoSymbolModel2(project, arrayOf(PyGotoSymbolContributor()))
}
