/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * 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.android.tools.idea.templates

import com.android.annotations.concurrency.GuardedBy
import com.android.annotations.concurrency.Slow
import com.android.tools.idea.actions.NewAndroidComponentAction
import com.android.tools.idea.device.FormFactor
import com.android.tools.idea.flags.StudioFlags
import com.android.tools.idea.model.AndroidModel
import com.android.tools.idea.npw.model.ProjectSyncInvoker
import com.android.tools.idea.npw.model.ProjectSyncInvoker.DefaultProjectSyncInvoker
import com.android.tools.idea.npw.model.RenderTemplateModel
import com.android.tools.idea.npw.model.RenderTemplateModel.Companion.fromFacet
import com.android.tools.idea.npw.project.getModuleTemplates
import com.android.tools.idea.npw.project.getPackageForPath
import com.android.tools.idea.npw.template.ChooseActivityTypeStep
import com.android.tools.idea.npw.template.ChooseFragmentTypeStep
import com.android.tools.idea.npw.template.TemplateResolver
import com.android.tools.idea.ui.wizard.StudioWizardDialogBuilder
import com.android.tools.idea.util.androidFacet
import com.android.tools.idea.wizard.model.ModelWizard
import com.android.tools.idea.wizard.model.SkippableWizardStep
import com.android.tools.idea.wizard.model.WizardModel
import com.android.tools.idea.wizard.template.Category
import com.android.tools.idea.wizard.template.Template
import com.android.tools.idea.wizard.template.WizardUiContext
import com.google.common.collect.Table
import com.google.common.collect.TreeBasedTable
import com.intellij.ide.actions.NonEmptyActionGroup
import com.intellij.openapi.actionSystem.ActionGroup
import com.intellij.openapi.actionSystem.ActionManager
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.actionSystem.DefaultActionGroup
import com.intellij.openapi.actionSystem.LangDataKeys
import icons.AndroidIcons
import org.jetbrains.android.util.AndroidBundle.message
import org.jetbrains.annotations.PropertyKey

/**
 * Handles locating templates and providing template metadata
 */
class TemplateManager private constructor() {
  /** Lock protecting access to [_categoryTable]  */
  private val CATEGORY_TABLE_LOCK = Any()

  /** Table mapping (Category, Template Name) -> Template File  */
  @GuardedBy("CATEGORY_TABLE_LOCK")
  private var _categoryTable: Table<Category, String, Template>? = null

  @get:GuardedBy("CATEGORY_TABLE_LOCK")
  private val categoryTable: Table<Category, String, Template>?
    get() {
      if (_categoryTable == null) {
        reloadCategoryTable()
      }
      return _categoryTable
    }

  private val topGroup = DefaultActionGroup("AndroidTemplateGroup", false)

  @Slow
  fun getTemplateCreationMenu(): ActionGroup {
    refreshDynamicTemplateMenu()
    return topGroup
  }

  @Slow
  fun refreshDynamicTemplateMenu() = synchronized(CATEGORY_TABLE_LOCK) {
    topGroup.apply {
      removeAll()
      addSeparator()
    }

    val am = ActionManager.getInstance()
    reloadCategoryTable() // Force reload
    for (category in categoryTable!!.rowKeySet()) {
      // Create the menu group item
      val categoryGroup: NonEmptyActionGroup = object : NonEmptyActionGroup() {
        override fun update(e: AnActionEvent) {
          updateAction(e, category.name, childrenCount > 0, false)
        }
      }
      categoryGroup.isPopup = true
      fillCategory(categoryGroup, category, am)
      topGroup.add(categoryGroup)
      setPresentation(category, categoryGroup)
    }
  }

  @GuardedBy("CATEGORY_TABLE_LOCK")
  private fun fillCategory(categoryGroup: NonEmptyActionGroup, category: Category, am: ActionManager) {
    val categoryRow = _categoryTable!!.row(category)

    fun addCategoryGroup(category: Category, name: String, @PropertyKey(resourceBundle = "messages.AndroidBundle") messageKey: String) {
      val galleryAction: AnAction = object : AnAction() {
        override fun update(e: AnActionEvent) {
          updateAction(e, "Gallery...", true, true)
        }

        override fun actionPerformed(e: AnActionEvent) {
          showWizardDialog(e, category.name, message(messageKey, FormFactor.MOBILE.id), "New $name")
        }
      }
      categoryGroup.add(galleryAction)
      categoryGroup.addSeparator()
      setPresentation(category, galleryAction)
    }

    if (category == Category.Activity) {
      addCategoryGroup(category, "Android Activity", "android.wizard.activity.add")
    }

    if (StudioFlags.NPW_SHOW_FRAGMENT_GALLERY.get() && category == Category.Fragment) {
      addCategoryGroup(category, "Android Fragment", "android.wizard.fragment.add")
    }

    for (templateName in categoryRow.keys) {
      val template = _categoryTable!![category, templateName]
      val templateAction = NewAndroidComponentAction(category, templateName, template.minSdk, template.minCompileSdk, template.constraints)
      val actionId = ACTION_ID_PREFIX + category + templateName
      am.replaceAction(actionId, templateAction)
      categoryGroup.add(templateAction)
    }

    val providers = AdditionalTemplateActionsProvider.EP_NAME.extensionList
    for (provider in providers) {
      for (anAction in provider.getAdditionalActions(category)) {
        categoryGroup.add(anAction)
      }
    }
  }

  @Slow
  @GuardedBy("CATEGORY_TABLE_LOCK")
  private fun reloadCategoryTable() {
    _categoryTable = TreeBasedTable.create()

    TemplateResolver.getAllTemplates()
      .filter { WizardUiContext.MenuEntry in it.uiContexts }
      .forEach { addTemplateToTable(it) }
  }

  @GuardedBy("CATEGORY_TABLE_LOCK")
  private fun addTemplateToTable(template: Template, userDefinedTemplate: Boolean = false) = with(template) {
    if (category == Category.Compose && !StudioFlags.COMPOSE_WIZARD_TEMPLATES.get()) {
      return
    }
    val existingTemplate = _categoryTable!![category, name]
    if (existingTemplate == null || template.revision > existingTemplate.revision) {
      _categoryTable!!.put(category, name, template)
    }
  }

  companion object {
    /**
     * A directory relative to application home folder where we can find an extra template folder. This lets us ship more up-to-date
     * templates with the application instead of waiting for SDK updates.
     */
    private const val CATEGORY_ACTIVITY = "Activity"
    private const val CATEGORY_FRAGMENT = "Fragment"
    private const val ACTION_ID_PREFIX = "template.create."

    @JvmStatic
    val instance = TemplateManager()

    private fun updateAction(event: AnActionEvent, actionText: String?, visible: Boolean, disableIfNotReady: Boolean) {
      val module = event.getData(LangDataKeys.MODULE)
      val facet = module?.androidFacet
      val isProjectReady = facet != null && AndroidModel.get(facet) != null
      event.presentation.apply {
        text = actionText + (" (Project not ready)".takeUnless { isProjectReady } ?: "")
        isVisible = visible && facet != null && AndroidModel.isRequired(facet)
        isEnabled = !disableIfNotReady || isProjectReady
      }
    }

    private fun showWizardDialog(e: AnActionEvent, category: String, commandName: String, dialogTitle: String) {
      val projectSyncInvoker: ProjectSyncInvoker = DefaultProjectSyncInvoker()
      val module = LangDataKeys.MODULE.getData(e.dataContext)!!
      val targetFile = CommonDataKeys.VIRTUAL_FILE.getData(e.dataContext)!!
      var targetDirectory = targetFile
      if (!targetDirectory.isDirectory) {
        targetDirectory = targetFile.parent
        assert(targetDirectory != null)
      }
      val facet = module.androidFacet
      assert(facet != null && AndroidModel.get(facet) != null)
      val moduleTemplates = facet!!.getModuleTemplates(targetDirectory)
      assert(moduleTemplates.isNotEmpty())
      val initialPackageSuggestion = facet.getPackageForPath(moduleTemplates, targetDirectory)
      val renderModel = fromFacet(
        facet, initialPackageSuggestion, moduleTemplates[0],
        commandName, projectSyncInvoker, true
      )
      val chooseTypeStep: SkippableWizardStep<WizardModel>
      chooseTypeStep = when (category) {
        CATEGORY_ACTIVITY -> ChooseActivityTypeStep.forActivityGallery(renderModel, targetDirectory)
        CATEGORY_FRAGMENT -> ChooseFragmentTypeStep(renderModel, FormFactor.MOBILE, targetDirectory)
        else -> throw RuntimeException("Invalid category name: $category")
      }
      val wizard = ModelWizard.Builder().addStep(chooseTypeStep).build()
      StudioWizardDialogBuilder(wizard, dialogTitle).build().show()
    }

    private fun setPresentation(category: Category, categoryGroup: AnAction) {
      categoryGroup.templatePresentation.apply {
        icon = AndroidIcons.Android
        text = category.name
      }
    }
  }
}